Compare commits

...

180 Commits

Author SHA1 Message Date
fujie
eb79bc9633 fix(tools): release openwebui-skills-manager v0.2.1
- Add GitHub skills-directory auto-discovery for install_skill batch install from tree root URLs.

- Harden language detection with frontend-first fallback (__event_call__ + timeout), then headers/profile.

- Bump plugin/docs versions to 0.2.1 and sync bilingual README/docs/index entries.
2026-02-28 23:06:08 +08:00
fujie
0c7d427b93 chore: cleanup debug files and update plugin configuration 2026-02-28 16:39:41 +08:00
fujie
07bc5f027e feat(skills-manager): add openwebui_id and fix tool type sync bug 2026-02-28 16:14:38 +08:00
fujie
701fc3e906 docs(skills-manager): add skill installation examples for single and batch URLs 2026-02-28 15:53:04 +08:00
fujie
d392af66c9 chore: rename update_pipe.py to deploy_pipe.py to reflect its creation capabilities and update skills reference 2026-02-28 15:29:46 +08:00
fujie
67cf86fb26 fix(pipes): yield artifacts string directly to stream flow avoiding emitter replacement 2026-02-28 15:21:28 +08:00
fujie
fe98b0e007 fix(pipes): fallback artifacts mode to using direct view_url iframe to bypass openwebui srcdoc sandbox cdn crash 2026-02-28 14:58:56 +08:00
fujie
3236d19e28 fix(pipes): restore corrupted isinstance check + add frontend console debug tracing 2026-02-28 14:35:53 +08:00
fujie
354c1eee6b chore(pipes): add debug tracing for pending_embeds lifecycle 2026-02-28 14:30:38 +08:00
fujie
6b3eb8064b fix(pipes): align artifacts internal array type tracking with stream loops 2026-02-28 14:17:05 +08:00
fujie
f32e90e182 feat(pipes): automate artifacts html generation via emitter message append 2026-02-28 13:48:53 +08:00
fujie
8001ab18ee feat(pipes): update richui mode to send raw HTML content instead of an iframe tag 2026-02-28 13:11:03 +08:00
fujie
dcfde9c0dc fix(pipes): revert artifacts iframe to barebone structure to avoid OpenWebUI markdown parsing issues 2026-02-28 13:06:10 +08:00
fujie
dbcf7421ea feat(pipes): simplify richui iframe tag to give full styling control to openwebui emitter 2026-02-28 13:04:10 +08:00
fujie
1705baf976 feat(pipes): unrestrict richui iframe height and apply generous sandbox policies 2026-02-28 13:01:38 +08:00
fujie
8e8d478ece fix(pipes): inject explicit sandbox policies to artifacts iframe to mitigate client-side block 2026-02-28 12:57:22 +08:00
fujie
acc9cd7ff2 fix(pipes): clarify ANTI-INLINE rule to allow iframe output and hardcode iframe shadow 2026-02-28 12:37:49 +08:00
fujie
e4582c3197 feat(pipes): optimize richui vs artifacts selection and enforce fullscreen button 2026-02-28 12:23:10 +08:00
fujie
d0eb72467d feat(pipes): enforce ANTI-INLINE HTML generation rule 2026-02-28 12:16:19 +08:00
fujie
6b6e62398a docs: add skill demo GIF asset 2026-02-28 06:12:13 +08:00
fujie
fd22ed8fa0 docs: use .gif instead of .mov for Skill demo in README 2026-02-28 05:51:02 +08:00
fujie
4fccd1893e docs: use absolute raw GitHub URL for video embedding 2026-02-28 05:44:21 +08:00
fujie
a74e03fff8 docs: use HTML video tag for README video embedding compatibility 2026-02-28 05:41:38 +08:00
fujie
850838226d docs: add skill visual agent demo video to home README 2026-02-28 05:37:04 +08:00
fujie
a52ac34d59 refactor(pipes): add video (MOV/MP4) embedding support to instructions 2026-02-28 05:12:50 +08:00
fujie
3263ab9db6 docs: enhance GitHub Copilot SDK Pipe description in home READMEs
- highlight autonomous agent capabilities
- add v0.9.0 key leaps: Skills Revolution, Secure Isolation, Interactive Delivery
2026-02-28 05:10:39 +08:00
fujie
7c7daef30b refactor(pipes): optimize gif embedding and detection
- update BASE_GUIDELINES to explicitly allow direct GIF embedding
- update publish_file_from_workspace to support common image formats
2026-02-28 04:56:28 +08:00
fujie
64754ba26b refactor(pipes): optimize artifacts prompt for HTML embeds
- Explicitly instruct AI to wrap iframe in html code blocks in artifacts mode
- Clarify guidelines to distinguish between artifacts and richui delivery
2026-02-28 04:16:55 +08:00
github-actions[bot]
4188410d61 chore: update community stats - new plugin added (24 -> 25) 2026-02-27 20:12:34 +00:00
Fu-Jie
0c7201902c feat(github-copilot-sdk): add workspace skills support (v0.9.0) (#51)
* feat(github-copilot-sdk): add workspace skills support

- Introduce ENABLE_WORKSPACE_SKILLS valve to enable/disable workspace custom tools discovery
- Modify _build_session_config() to auto-load tools from .copilot-skills/ directory
- Add workspace_skills_example.py template with 3 working example tools
- Update README.md and README_CN.md with Workspace Skills guide and usage examples
- Create v0.9.0.md and v0.9.0_CN.md release notes
- Sync version to all docs files (index.md, index.zh.md, and main docs)
- Bump version from 0.8.0 to 0.9.0 across all 7+ locations

* docs: establish temp files handling policy (project-based, not /tmp)

- Add TEMP_FILES_POLICY.md guideline for all skills and workflows
- Update pr-submitter skill to use .temp/ directory instead of /tmp
- Update release-prep skill documentation with temp file convention
- Add .temp/ and .build/ entries to .gitignore
- Create internal policy memo in /memories/repo/

This policy ensures:
- All temporary files stay within project workspace (not system /tmp)
- Alignment with OpenWebUI workspace isolation principles
- Multi-user safety and cleanup traceability
- Consistent handling across all skills and development workflows

* fix(terminology): rename 'workspace skills' to 'workspace custom tools' for accuracy

The term 'Skills' in Anthropic context refers to instruction-based frameworks
(SKILL.md files with YAML frontmatter + markdown), not custom tool functions.

Our implementation uses @define_tool decorator to define custom tools that the
SDK auto-discovers from .copilot-skills/ directory. These are Tools, not Skills.

Changes:
- Rename ENABLE_WORKSPACE_SKILLS valve -> ENABLE_WORKSPACE_TOOLS
- Update all documentation (README, README_CN, docs, release notes)
- Fix section headings and descriptions throughout
- Ensure consistent terminology across all files

This is a terminology-only change; functionality remains identical.

* feat(pipes): release v0.9.0 of GitHub Copilot SDK Pipe

- Integrated OpenWebUI Skills Bridge and manage_skills tool
- Reinforced status bar stability with session_finalized logic
- Added persistent SDK config directory support

* docs(pipes): add comprehensive guides and v0.9.0 notes for Copilot SDK

- Added skill manager and best practices guides
- Added publishing tool documentation
- Included v0.9.0 release notes and deployment script
- Updated usage guides
2026-02-28 03:50:56 +08:00
Fu-Jie
f47c3f6354 Fix formatting for Open WebUI Prompt Plus entry
Updated README.md to improve formatting of the Open WebUI Prompt Plus section.
2026-02-26 13:15:49 +08:00
Copilot
272245d911 docs: add OOpenWebUI official newsletter featured recognition to Smart Mind Map, Markdown Normalizer, and Prompt Plus (#52)
* Initial plan

* docs: add OpenWebUI official newsletter featured recognition

- Add newsletter featured callout to Smart Mind Map README.md, README_CN.md, and docs
- Add newsletter featured callout to Markdown Normalizer README.md, README_CN.md, and docs
- Add newsletter featured badge to Prompt Plus in root README.md and README_CN.md
- Reference both newsletters: Jan 28, 2026 and Feb 3, 2026

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>

* docs: fix newsletter links to match actual featured issue per plugin

- Smart Mind Map: link only to Feb 3, 2026 (second newsletter)
- Markdown Normalizer: link only to Jan 28, 2026 (first newsletter)
- Prompt Plus (root READMEs): already correct, no change needed

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-26 13:12:13 +08:00
fujie
ce93464f47 chore(skills): sync all github copilot skills to gemini 2026-02-26 01:42:13 +08:00
fujie
c658e379c0 docs(skills): clarify community-publisher is for new posts only 2026-02-26 01:41:25 +08:00
fujie
ab28465dd5 feat(skills): add openwebui-community-publisher skill 2026-02-26 01:33:49 +08:00
github-actions[bot]
d22ba88f33 chore: update community stats - new plugin added (23 -> 24) 2026-02-25 17:28:32 +00:00
Fu-Jie
db33f44cbc feat(plugins): release Copilot SDK Pipe v0.8.0 and Files Filter v0.1.3 (#50)
* feat(plugins): release copilot sdk pipe v0.8.0 and files filter v0.1.3

- Add P1~P4 conditional tool filtering and admin/server gating behavior

- Fix artifact publishing reliability, strict /api file URLs, and HTML preview/download delivery

- Update bilingual README/docs, release notes, and filter matching/debug improvements

* fix(docs): remove duplicate code block in tool-filtering zh doc

- Remove incorrectly placed duplicate 'if not is_enabled: continue' block
  outside code fence on line 161-163 of copilot-sdk-tool-filtering.zh.md
- Addresses review comment from gemini-code-assist (#50)
2026-02-26 01:05:31 +08:00
fujie
5b6dddd517 docs(agent): sync source-code-analyzer skill to .github/skills 2026-02-24 23:08:18 +08:00
fujie
c8ba7c99af feat(agent): inject source-code-analyzer skill and update repo rules
- Add source-code-analyzer skill with global/plugin-specific paths\n- Update GEMINI.md with External Auth and Source Sensing rules\n- Explicitly authorize Antigravity to read core component source code
2026-02-24 23:07:44 +08:00
fujie
81279845e2 chore(skills): sync .gemini and .github skills and fix i18n validator 2026-02-24 22:19:48 +08:00
fujie
6b39531fbc feat(skills): add 6 generalized AI-driven development skills
- version-bumper: automated multi-file version synchronization
- plugin-scaffolder: standardized 12-language i18n template generation
- doc-mirror-sync: automated README to docs mirroring
- i18n-validator: dictionary key alignment analysis via AST
- gh-issue-replier: professional English reply with star-check logic
- gh-issue-scheduler: unanswered issue audit and action planning
2026-02-24 16:02:01 +08:00
fujie
377534e6c9 feat(project): sync engineering standards and finalize markdown-normalizer v1.2.7
- Update .github/copilot-instructions.md with latest i18n and naming standards
- Add docs/development/issue-reply-guide.md for professional community engagement
- Sync all documentation (MKDocs, READMEs, Docs) to v1.2.7
- Include CI/CD and Agent instruction templates for better automation
2026-02-24 15:13:52 +08:00
fujie
2da934dd92 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
2026-02-24 15:05:25 +08:00
fujie
18ada2a177 docs: fix table header alignment and column count in READMEs 2026-02-23 14:43:28 +08:00
fujie
a5fbc8bed9 docs: add Actively Developed Projects section with GitHub Copilot SDK Pipe 2026-02-23 14:42:14 +08:00
github-actions[bot]
904eeb0ad0 chore: update community stats - new plugin added (22 -> 23) 2026-02-22 19:12:33 +00:00
fujie
9c70110e1d docs: refine wording in English v0.7.0.md (use UI instead of interface) 2026-02-23 02:42:58 +08:00
fujie
9af6a8c9bd docs: refine wording in v0.7.0_CN.md (UI instead of interface) 2026-02-23 02:42:10 +08:00
fujie
ac948023e3 docs: add Chinese version of v0.7.0 post 2026-02-23 02:41:19 +08:00
fujie
512b606827 docs: add emoji and subtitle to v0.7.0.md 2026-02-23 02:40:24 +08:00
fujie
fc9f1ccb43 feat(pipes): v0.7.0 final release with native tool UI and CLI integration
- Core: Adapt to OpenWebUI native tool call UI and thinking process visualization
- Infra: Bundle Copilot CLI via pip package (no more background curl installation)
- Fix: Resolve "Error getting file content" on OpenWebUI v0.8.0+ via absolute paths
- i18n: Add native localization for status messages in 11 languages
- UX: Optimize reasoning status display logic and cleanup legacy code
2026-02-23 02:33:59 +08:00
fujie
272b959a44 fix(actions): fix white background bleed in dark mode when viewport is narrow 2026-02-22 00:24:37 +08:00
fujie
0bde066088 fix: correct Top 6 plugin name-data mapping to match Gist badge order 2026-02-22 00:10:04 +08:00
fujie
6334660e8d docs: add root README update date sync rule to consistency maintenance 2026-02-22 00:06:43 +08:00
fujie
c29d84f97a docs: update Smart Mind Map release date in root readmes to 2026-02-22 2026-02-22 00:02:51 +08:00
fujie
aac2e89022 chore: update smart mind map plugin image. 2026-02-22 00:00:19 +08:00
fujie
fea812d4f4 ci: remove redundant release title from github release body 2026-02-21 23:49:36 +08:00
fujie
b570cbfcde docs(filters): fix broken link to workflow guide in mkdocs strict build 2026-02-21 23:47:48 +08:00
fujie
adc5e0a1f4 feat(filters): release v1.3.0 for async context compression
- Add native i18n support across 9 languages
- Implement non-blocking frontend log emission for zero TTFB delay
- Add token_usage_status_threshold to intelligently control status notifications
- Automatically detect and skip compression for copilot_sdk models
- Set debug_mode default to false for a quieter production environment
- Update documentation and remove legacy bilingual code
2026-02-21 23:44:12 +08:00
fujie
04b8108890 chore: ignore and stop tracking .git-worktrees 2026-02-21 21:50:35 +08:00
fujie
f1ba03e3bd Merge remote-tracking branch 'origin/main' into copilot/sub-pr-42
# Conflicts:
#	plugins/actions/smart-mind-map/README.md
#	plugins/actions/smart-mind-map/README_CN.md
#	plugins/actions/smart-mind-map/smart_mind_map.py
#	plugins/actions/smart-mind-map/smart_mind_map_cn.py
2026-02-21 18:04:48 +08:00
fujie
cdd9950973 docs: update pr submission guidelines to require gh tool 2026-02-21 17:54:09 +08:00
fujie
473012fa6f feat(actions): release Smart Mind Map v1.0.0 - a milestone with Native i18n & Direct Embed 2026-02-21 17:50:44 +08:00
fujie
1bbddb2222 feat(pipe): show Copilot CLI install progress during first run 2026-02-15 00:18:27 +08:00
copilot-swe-agent[bot]
dc66610cb2 docs: Align with copilot-instructions.md standards and update all repo references
Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-13 03:36:30 +00:00
copilot-swe-agent[bot]
655b5311cf chore: Update repository references from awesome-openwebui to openwebui-extensions
Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-13 03:31:06 +00:00
copilot-swe-agent[bot]
4390ee2085 Initial plan 2026-02-13 03:29:45 +00:00
fujie
6bf3656d30 docs: rename Awesome OpenWebUI and OpenWebUI Extras to OpenWebUI Extensions 2026-02-13 11:10:48 +08:00
google-labs-jules[bot]
bfb2039095 feat: Add full i18n support, security fixes, and zh-TW to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 18 languages (including explicit zh-TW support).
- Implemented robust language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Added base language fallback (e.g., fr-BE -> fr-FR) and variant mapping.
- Fixed critical security vulnerabilities:
    - Prevented JS injection by safely escaping IDs with `json.dumps`.
    - Prevented XSS by sanitizing user input and language codes.
    - Prevented DoS crashes from curly braces in LLM output by replacing `.format()` with safe string replacement.
- Fixed regex regression by using standard strings with escaped backslashes.
- Restored clickable "Markmap" link in the footer.
- Verified all changes with comprehensive unit and security tests.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 21:05:45 +00:00
google-labs-jules[bot]
86091f77cf feat: Security and i18n improvements for Smart Mind Map plugin
- Fixed high-severity XSS and JS injection vulnerabilities by safely escaping IDs and user input using `json.dumps` and HTML entity encoding.
- Prevented potential DoS crashes caused by curly braces in LLM output by replacing `.format()` with safe string replacement.
- Refactored language resolution into a `_resolve_language` helper method, implementing base language fallback (e.g., `fr-BE` -> `fr-FR`).
- Refactored date formatting to use a cleaner, dictionary-based approach.
- Consolidated i18n logic into a single file with robust fallback handling.
- Verified all changes with comprehensive unit and security tests.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 17:41:52 +00:00
google-labs-jules[bot]
eb223e3e75 feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 18 languages (en-US, ko-KR, fr-FR, es-AR, en-CA, fr-CA, ja-JP, de-DE, zh-HK, it-IT, zh-CN, en-GB, es-MX, id-ID, es-ES, de-AT, en-AU, vi-VN, zh-TW).
- Implemented automatic language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Added explicit support for zh-TW (Traditional Chinese) with correct translations.
- Updated HTML/JS templates to use injected translations.
- Restored clickable "Markmap" link in the footer for all languages.
- Fixed SyntaxWarning in regex strings by properly escaping backslashes in standard strings.
- Implemented robust UI translation loading to prevent crashes on missing keys.
- Verified frontend rendering with Playwright and backend logic with unit tests.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 17:15:50 +00:00
google-labs-jules[bot]
d1bbbd9071 feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 18 languages (en-US, ko-KR, fr-FR, es-AR, en-CA, fr-CA, ja-JP, de-DE, zh-HK, it-IT, zh-CN, en-GB, es-MX, id-ID, es-ES, de-AT, en-AU, vi-VN, zh-TW).
- Implemented automatic language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Added explicit support for zh-TW (Traditional Chinese) with correct translations.
- Updated HTML/JS templates to use injected translations.
- Restored clickable "Markmap" link in the footer for all languages.
- Fixed SyntaxWarning in regex strings.
- Verified frontend rendering with Playwright.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 17:06:28 +00:00
google-labs-jules[bot]
840c77ea2f feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 18 languages (including explicit zh-TW support).
- Implemented automatic language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Added fallback mapping for regional variants (e.g., es-AR -> es-ES).
- Updated HTML/JS templates to use injected translations.
- Fixed SyntaxWarning in regex strings.
- Verified frontend rendering with Playwright and backend logic with unit tests.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 16:54:48 +00:00
google-labs-jules[bot]
91ba7df086 feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 17 languages (en-US, ko-KR, fr-FR, es-AR, en-CA, fr-CA, ja-JP, de-DE, zh-HK, it-IT, zh-CN, en-GB, es-MX, id-ID, es-ES, de-AT, en-AU, vi-VN).
- Implemented automatic language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Added fallback mapping for regional variants (e.g. zh-TW -> zh-HK, es-AR -> es-ES).
- Updated HTML/JS templates to use injected translations.
- Fixed SyntaxWarning in regex strings.
- Verified frontend rendering with Playwright.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 16:46:27 +00:00
google-labs-jules[bot]
fa636c7bc5 feat: Add full i18n support to Smart Mind Map plugin
- Consolidated smart_mind_map.py and smart_mind_map_cn.py into a single file.
- Added TRANSLATIONS dictionary supporting 17 languages (en-US, ko-KR, fr-FR, es-AR, en-CA, fr-CA, ja-JP, de-DE, zh-HK, it-IT, zh-CN, en-GB, es-MX, id-ID, es-ES, de-AT, en-AU, vi-VN).
- Implemented automatic language detection with fallback to browser/local storage.
- Added localized date formatting for various locales.
- Updated HTML/JS templates to use injected translations.
- Fixed SyntaxWarning in regex strings.
- Verified frontend rendering with Playwright.

Co-authored-by: Fu-Jie <33599649+Fu-Jie@users.noreply.github.com>
2026-02-12 16:33:04 +00:00
fujie
a5ad295d38 ci: clean up unused variables in stats workflow 2026-02-11 14:19:28 +08:00
fujie
e1f70d52a5 ci: remove push trigger for merged feature branch 2026-02-11 14:15:58 +08:00
fujie
015c22063a ci: remove fetch-depth 0, history data already persisted in Gist 2026-02-11 14:14:55 +08:00
fujie
0ea95ceefa feat: 自动化统计系统重构 - 动态徽章 + Gist SVG 图表 + 历史数据恢复 2026-02-11 14:11:26 +08:00
fujie
1192c71453 fix: merge Gist+local history and rebuild from community-stats.json 2026-02-11 14:04:03 +08:00
fujie
0b5663636f chore: hydrate stats history with recovered data (38 days record) 2026-02-11 14:00:17 +08:00
fujie
1736a1bfbf feat: auto-rebuild stats history from git logs if local/gist data is missing 2026-02-11 13:53:55 +08:00
fujie
d7c25aa973 fix: relax history requirements for chart generation 2026-02-11 13:50:42 +08:00
fujie
d71b4a7351 chore: add logging to upload_chart_svg to debug silent failure 2026-02-11 13:49:08 +08:00
fujie
a05697df70 fix: correct vl_spec syntax and use POST for Kroki 2026-02-11 13:47:23 +08:00
fujie
b355c3f0c1 feat: implement SVG generation and Gist upload logic in stats script 2026-02-11 13:42:27 +08:00
fujie
30f2aed68a feat: switch to static Gist SVG for activity chart (no more daily README commits) 2026-02-11 13:41:41 +08:00
fujie
50c549b260 chore: apply dynamic version badges to README 2026-02-11 13:36:28 +08:00
fujie
2a75580831 style: apply colored badges to post type statistics in docs 2026-02-11 13:36:05 +08:00
fujie
4032746243 style: enhance stats docs with colored badges for post types 2026-02-11 13:34:14 +08:00
fujie
871e76b1df chore: manual stats update (latest history & chart) 2026-02-11 13:32:27 +08:00
fujie
954ebad8b2 feat: sync docs chart with README chart (Vega-Lite) 2026-02-11 13:31:14 +08:00
fujie
fa5d962152 feat: use dynamic badges for plugin versions, remove version changes as commit trigger 2026-02-11 13:28:19 +08:00
fujie
2ac8d4b14f ci: remove points and followers as commit triggers since they are now dynamic badges 2026-02-11 13:26:00 +08:00
fujie
c86b27a0c1 ci: add dedicated daily workflow for chart updates at 01:10 Beijing time 2026-02-11 13:24:17 +08:00
fujie
2381c5080e fix: revert chart to embedded data - Kroki server-side rendering cannot fetch external URLs 2026-02-11 13:23:05 +08:00
fujie
0394be7d16 chore: update READMEs and docs with stable Gist-based chart URL 2026-02-11 13:18:51 +08:00
fujie
7c9bf4082a feat: sync activity chart in docs with README configuration 2026-02-11 13:16:02 +08:00
fujie
8621d178ae feat: restore external Gist data source for stable chart URL 2026-02-11 13:11:54 +08:00
fujie
20a7d57b5b fix: revert to embedded activity chart data to resolve loading failures 2026-02-11 13:09:23 +08:00
fujie
8f72e25671 perf: use external Gist data source for trend chart to keep URL static 2026-02-11 13:04:36 +08:00
fujie
b7e62e63e0 docs: restore missing language switcher in README 2026-02-11 12:59:08 +08:00
fujie
bbccffa95b style: move activity chart to end of stats section and add updated badge to top6 table 2026-02-11 12:56:30 +08:00
fujie
b9104702ac fix: use dynamic badges for auto-updated timestamp to ensure real-time accuracy 2026-02-11 12:54:45 +08:00
fujie
015b0d98ec style: embed full-history activity chart into stats section and refine top 6 table 2026-02-11 12:52:14 +08:00
fujie
fc56ea7faa style: move activity chart to bottom and use vega-lite for better visuals 2026-02-11 12:46:24 +08:00
fujie
e1c2261537 fix: implement safe badge keys and add dynamic upvote/save badges 2026-02-11 12:41:16 +08:00
fujie
93e8e3bee2 fix: remove duplicate saves entry and restore comments entry formatting 2026-02-11 12:37:51 +08:00
fujie
1fb2cccd58 fix: resolve type error in gist sync and implement full English localization for charts 2026-02-11 12:35:45 +08:00
fujie
b34ce0b075 docs: finalize Zero-Commit dynamic reports with Kroki charts and dynamic badges 2026-02-11 12:29:39 +08:00
fujie
49efcb7e4d feat: implement Zero-Commit dynamic Mermaid charts via Kroki server-side rendering 2026-02-11 12:26:09 +08:00
fujie
8d334a48b9 feat: transition stats hosting to Gist-first model to minimize repository commits 2026-02-11 12:23:10 +08:00
fujie
16882bf9e5 data: finalize community stats with full historical data and dynamic badges 2026-02-11 12:21:56 +08:00
fujie
dc0366aab2 feat: enable live stats for community reports via Gist dynamic badges 2026-02-11 12:19:16 +08:00
fujie
6d080d3a28 data: reconstruct full stats history from git logs and update reports 2026-02-11 12:15:22 +08:00
fujie
e50a55ee11 feat: enhance Mermaid visualizations with multi-series trends, distribution pie, and impact analysis 2026-02-11 12:13:29 +08:00
fujie
edbd75e5dc fix: URL encode Gist raw endpoints for reliable Shields.io badge rendering 2026-02-11 12:12:37 +08:00
fujie
387ca8788b feat: use dynamic badges for Top 6 plugin statistics in README 2026-02-11 12:10:46 +08:00
fujie
cfb15808ef docs: finalize dynamic stats badges in READMEs 2026-02-11 12:09:11 +08:00
fujie
0424521380 feat: complete no-commit update system with dynamic badges and history sync 2026-02-11 12:08:05 +08:00
fujie
c2ea3b2479 feat: migrate stats display to dynamic Shields.io badges via Gist 2026-02-11 12:05:52 +08:00
fujie
a96a588141 style: reformat README stats section for better clarity and premium look 2026-02-11 12:01:54 +08:00
fujie
f34da0b263 feat: include per-post download stats in historical snapshots 2026-02-11 11:59:56 +08:00
fujie
80dce6e1de fix: compatibility with Python < 3.12 for f-strings with backslashes 2026-02-11 11:58:44 +08:00
fujie
080534d03b feat: implement Gist-based history tracking and enhanced stats categorization 2026-02-11 11:57:07 +08:00
fujie
a63d3e89ff feat: implement stats history, growth tracking, and mermaid trend charts 2026-02-11 11:41:12 +08:00
github-actions[bot]
0b9c242c0f chore: update community stats - points increased (270 -> 271) 2026-02-11 03:11:02 +00:00
github-actions[bot]
6f7ae4a304 chore: update community stats - points increased (269 -> 270) 2026-02-10 23:19:32 +00:00
github-actions[bot]
571adf33c5 chore: update community stats - points increased (268 -> 269), followers increased (219 -> 220) 2026-02-10 21:20:45 +00:00
github-actions[bot]
813e2b8320 chore: update community stats - followers increased (218 -> 219) 2026-02-10 20:19:43 +00:00
github-actions[bot]
21ec586c68 chore: update community stats - points increased (266 -> 268), followers increased (217 -> 218) 2026-02-10 15:32:07 +00:00
fujie
e95a786420 docs: add core practical examples (Star Prediction & Video Processing) to README 2026-02-10 23:07:44 +08:00
github-actions[bot]
7773723b18 chore: update community stats - new plugin added (21 -> 22), plugin version updated, points increased (262 -> 266) 2026-02-10 14:35:09 +00:00
fujie
c547c1cee5 docs: fix broken relative links in example cases to resolve mkdocs build warnings 2026-02-10 21:41:15 +08:00
fujie
b04112a261 docs: add GitHub Copilot SDK pipe masterclass cases and documentation updates 2026-02-10 21:38:54 +08:00
github-actions[bot]
df977a7ccc chore: update community stats - followers increased (216 -> 217) 2026-02-10 10:26:05 +00:00
fujie
3986eb854f docs: modernize file delivery protocol and update tutorials 2026-02-10 17:01:18 +08:00
fujie
fe170bedb9 chore: remove sample_sales_data.csv (accidentally committed) 2026-02-10 16:23:20 +08:00
fujie
3504313f15 docs(workflow): optimize release format to English-only changelog 2026-02-10 16:20:47 +08:00
github-actions[bot]
e5e0f4cbcc chore: update community stats - plugin version updated 2026-02-10 07:30:30 +00:00
fujie
a7b244602f feat(pipe): release v0.6.2 - full-lifecycle file agent support 2026-02-10 14:55:16 +08:00
github-actions[bot]
3343e73848 chore: update community stats - followers increased (215 -> 216) 2026-02-10 04:51:12 +00:00
github-actions[bot]
7ab3e51d6f chore: update community stats - followers increased (214 -> 215) 2026-02-10 03:11:20 +00:00
github-actions[bot]
303d21c73d chore: update community stats - followers increased (213 -> 214) 2026-02-09 21:18:32 +00:00
github-actions[bot]
054af87e6e chore: update community stats - points increased (261 -> 262), followers increased (212 -> 213) 2026-02-09 19:34:12 +00:00
github-actions[bot]
991570d025 chore: update community stats - plugin version updated 2026-02-09 17:24:09 +00:00
fujie
5a5261d184 chore(release): bump github-copilot-sdk to 0.6.1 and update READMEs/CHANGELOG 2026-02-10 01:04:13 +08:00
fujie
8cdc7723d2 docs(pipes): update github-copilot-sdk README version to 0.6.1 2026-02-10 01:04:02 +08:00
github-actions[bot]
a167f51026 chore: update community stats - followers increased (211 -> 212) 2026-02-09 15:25:46 +00:00
fujie
03ff69f9e0 docs: synchronize README_CN.md with the latest premium layout and market links 2026-02-09 22:12:21 +08:00
fujie
62c69a9a41 fix: restore <b> tags in summary for proper rendering on GitHub 2026-02-09 22:09:14 +08:00
fujie
9bf2a5d2a2 docs: link Star Features titles to OpenWebUI Community market 2026-02-09 22:07:56 +08:00
fujie
13aed46c05 docs: shorten community market badges to Get-Market for better visual balance 2026-02-09 22:06:37 +08:00
fujie
02a1668979 docs: add direct Community Market download badges to Star Features 2026-02-09 22:04:46 +08:00
fujie
9760ccb243 style: silence MD033 lint errors by wrapping with markdownlint-disable comments 2026-02-09 22:00:45 +08:00
fujie
e2c705fe15 style: reduce HTML elements in README.md collapsible sections and fix summary bold 2026-02-09 21:59:43 +08:00
fujie
37c7bf73c0 style: fix table formatting lint errors in README.md 2026-02-09 21:58:55 +08:00
fujie
447e791ab6 style: fix lint global errors and synchronize stats generator 2026-02-09 21:58:27 +08:00
fujie
cde685a364 docs: synchronize project contents with disk and add missing filters 2026-02-09 21:55:54 +08:00
fujie
b00206b063 docs: implement collapsible project content layout in home README 2026-02-09 21:53:47 +08:00
fujie
e0a838e512 docs: finalize home README with 5 star features and BYOK highlight (pure English) 2026-02-09 21:51:36 +08:00
fujie
b9f4f5f1d6 chore: update project README with star feature highlight (English only) 2026-02-09 21:47:54 +08:00
github-actions[bot]
c1afd1fa23 chore: update community stats - points increased (259 -> 261), followers increased (210 -> 211) 2026-02-09 13:37:24 +00:00
Jeff
eaeaadaf12 Merge pull request #39 from Fu-Jie/add-abaroni-contributor
chore: add @abaroni as contributor
2026-02-09 20:27:07 +08:00
fujie
ee70c6629e chore: add @abaroni as contributor (ideas) 2026-02-09 20:26:27 +08:00
github-actions[bot]
692971c93c chore: update community stats - new plugin added (20 -> 21), plugin version updated 2026-02-09 12:25:10 +00:00
fujie
e17818bf6c chore: re-trigger release for v0.6.0 2026-02-09 19:54:49 +08:00
fujie
c5c9fd9d57 fix(ci): fix shell script error when commit messages contain backticks 2026-02-09 19:53:23 +08:00
fujie
5c9875d390 feat: add openwebui_id to the GitHub Copilot SDK files filter plugin metadata. 2026-02-09 19:48:41 +08:00
fujie
9185f88d40 feat: release github-copilot-sdk v0.6.0 and files-filter v0.1.2 2026-02-09 19:45:23 +08:00
github-actions[bot]
1fcad993ea chore: update community stats - followers increased (208 -> 210) 2026-02-09 03:10:29 +00:00
github-actions[bot]
1594ea3a20 chore: update community stats - followers increased (207 -> 208) 2026-02-09 00:44:14 +00:00
github-actions[bot]
ee681ddad9 chore: update community stats - followers increased (206 -> 207) 2026-02-08 21:11:27 +00:00
github-actions[bot]
881597fd51 chore: update community stats - followers increased (205 -> 206) 2026-02-08 07:21:06 +00:00
github-actions[bot]
5772b1c65f chore: update community stats - plugin version updated, points increased (258 -> 259) 2026-02-08 00:53:22 +00:00
fujie
3d4b4b96e8 fix(docs): Repair broken valves table in README 2026-02-08 08:33:02 +08:00
fujie
409d2f663f feat(copilot): Release v0.5.1 - Smarter BYOK, Tool Caching & Refined Docs 2026-02-08 08:21:32 +08:00
github-actions[bot]
de9948a5b0 chore: update community stats - followers increased (204 -> 205) 2026-02-07 23:12:20 +00:00
github-actions[bot]
0a51b4cfca chore: update community stats - points increased (257 -> 258) 2026-02-07 18:13:00 +00:00
github-actions[bot]
f8eb096300 chore: update community stats - plugin version updated 2026-02-07 11:08:46 +00:00
280 changed files with 22312 additions and 18573 deletions

147
.agent/rules/antigravity.md Normal file
View File

@@ -0,0 +1,147 @@
---
description: >
Antigravity development mode rules. Apply when the user requests high-speed iteration,
a quick prototype, or says "反重力开发" / "antigravity mode".
globs: "plugins/**/*.py"
always_on: false
---
# Antigravity Development Mode
> High-speed delivery + strict reversibility. Every decision must keep both roll-forward and rollback feasible.
---
## Core Principles
1. **Small, isolated edits** — one logical change per operation; no mixing refactor + feature.
2. **Deterministic interfaces** — function signatures and return shapes must not change without an explicit contract update.
3. **Multi-level fallback** — every I/O path has a degraded alternative (e.g., S3 → local → DB).
4. **Reversible by default** — every file write, API call, or schema change must have an undo path recorded or be idempotent.
---
## Mandatory Safety Patterns
### 1. Timeout Guards on All Frontend Calls
Any `__event_call__` or `__event_emitter__` JS execution MUST be wrapped:
```python
import asyncio
try:
result = await asyncio.wait_for(
__event_call__({"type": "execute", "data": {"code": js_code}}),
timeout=2.0
)
except asyncio.TimeoutError:
logger.warning("Frontend JS execution timed out; falling back.")
result = fallback_value
except Exception as e:
logger.error(f"Frontend call failed: {e}", exc_info=True)
result = fallback_value
```
JS side must also guard internally:
```javascript
try {
return (localStorage.getItem('locale') || navigator.language || 'en-US');
} catch (e) {
return 'en-US';
}
```
### 2. Path Sandbox Validation
Resolve every workspace path and verify it stays inside the repo root:
```python
import os
def _validate_workspace_path(path: str, workspace_root: str) -> str:
resolved = os.path.realpath(os.path.abspath(path))
root = os.path.realpath(workspace_root)
if not resolved.startswith(root + os.sep) and resolved != root:
raise PermissionError(f"Path escape detected: {resolved} is outside {root}")
return resolved
```
### 3. Dual-Channel Upload Fallback
Always try API first; fall back to DB/local on failure:
```python
async def _upload_file(self, filename: str, content: bytes) -> str:
# Channel 1: API upload (S3-compatible)
try:
url = await self._api_upload(filename, content)
if url:
return url
except Exception as e:
logger.warning(f"API upload failed: {e}; falling back to local.")
# Channel 2: Local file + DB registration
return await self._local_db_upload(filename, content)
```
### 4. Progressive Status Reporting
For tasks > 3 seconds, emit staged updates:
```python
await self._emit_status(emitter, "正在分析内容...", done=False)
# ... phase 1 ...
await self._emit_status(emitter, "正在生成输出...", done=False)
# ... phase 2 ...
await self._emit_status(emitter, "完成", done=True)
```
Always emit `done=True` on completion and `notification(error)` on failure.
### 5. Emitter Guard
Check before every emit to prevent crashes on missing emitter:
```python
if emitter and self.valves.SHOW_STATUS:
await emitter({"type": "status", "data": {"description": msg, "done": done}})
```
### 6. Exception Surface Rule
Never swallow exceptions silently. Every `except` block must:
- Log to backend: `logger.error(f"...: {e}", exc_info=True)`
- Notify user: `await self._emit_notification(emitter, f"处理失败: {str(e)}", "error")`
---
## Edit Discipline
| ✅ DO | ❌ DO NOT |
|-------|-----------|
| One function / one Valve / one method per edit | Mix multiple unrelated changes in one operation |
| Validate input at the function boundary | Assume upstream data is well-formed |
| Return early on invalid state | Nest complex logic beyond 3 levels |
| Check fallback availability before primary path | Assume primary path always succeeds |
| Log before and after expensive I/O | Skip logging for "obvious" operations |
---
## Rollback Checklist
Before completing an antigravity operation, confirm:
- [ ] No global state mutated on `self` (filter singleton rule)
- [ ] File writes are atomic or can be recreated
- [ ] Database changes are idempotent (safe to re-run)
- [ ] Timeout guards are in place for all async calls to external systems
- [ ] The user can observe progress through status/notification events
---
## References
- Full engineering spec: `.github/copilot-instructions.md` → Section: **Antigravity Development Mode**
- Design document: `docs/development/copilot-engineering-plan.md` → Section 5

View File

@@ -12,19 +12,22 @@ All plugins MUST follow the standard README template.
**Reference Template**: @docs/PLUGIN_README_TEMPLATE.md
### Language Requirements
- **English Version (`README.md`)**: The primary documentation source. Must follow the template strictly.
- **Chinese Version (`README_CN.md`)**: MUST be translated based on the English version (`README.md`) to ensure consistency in structure and content.
### Metadata Requirements
The metadata line must follow this format:
`**Author:** [Name](Link) | **Version:** [X.Y.Z] | **Project:** [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui) | **License:** MIT`
`**Author:** [Name](Link) | **Version:** [X.Y.Z] | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT`
### Structure Checklist
1. **Title & Description**
2. **Metadata Line** (Author, Version, Project, License)
3. **Preview** (Screenshots/GIFs)
4. **What's New** (Keep last 3 versions)
5. **Key Features**
6. **How to Use**
7. **Configuration (Valves)**
8. **Troubleshooting** (Must include link to GitHub Issues)
1. **Title & Description**
2. **Metadata Line** (Author, Version, Project, License)
3. **Preview** (Screenshots/GIFs)
4. **What's New** (Keep last 3 versions)
5. **Key Features**
6. **How to Use**
7. **Configuration (Valves)**
8. **Troubleshooting** (Must include link to GitHub Issues)

View File

@@ -0,0 +1,64 @@
---
name: test-copilot-pipe
description: Automotive deployment and testing of GitHub Copilot SDK Pipe plugin for frontend/backend status stability.
---
# 🤖 Skill: Test Copilot Pipe
This is a **universal testing framework** for publishing the latest `github_copilot_sdk.py` (Pipe) code to a local OpenWebUI instance and verifying it via an automated agent (`browser_subagent`).
## 🎯 Core Principles
- **Fixed Infrastructure**: The deployment script and the test entry URL are always static.
- **Dynamic Test Planning**: Specific test prompts and expectations (acceptance criteria) **must** be dynamically planned by you based on the code changes or specific user requests before execution.
---
## 🛠️ Static Environment Info
| Attribute | Fixed Value |
|------|--------|
| **Deployment Script** | `/Users/fujie/app/python/oui/openwebui-extensions/scripts/deploy_pipe.py` |
| **Python Path** | `/opt/homebrew/Caskroom/miniconda/base/envs/ai/bin/python3` |
| **Test URL** | `http://localhost:3003/?model=github_copilot_official_sdk_pipe.github_copilot_sdk-gpt-4.1` |
---
## 📋 Standard Workflow
### Step 1: Analyze Changes & Plan Test (Plan)
Before triggering the test, you must define the purpose of this test turn.
Example: *Modified tool calling logic -> Test prompt should trigger a specific tool; observe if the tool executes and returns the correct result.*
### Step 2: Deploy Latest Code (Deploy)
Use the `run_command` tool to execute the fixed update task:
```bash
/opt/homebrew/Caskroom/miniconda/base/envs/ai/bin/python3 /Users/fujie/app/python/oui/openwebui-extensions/scripts/deploy_pipe.py
```
> **Mechanism**: `deploy_pipe.py` automatically loads the API Key from `scripts/.env` in the same directory.
> **Verification**: Look for `✅ Successfully updated... version X.X.X` or `✅ Successfully created...`. If a 401 error occurs, remind the user to generate a new API Key in OpenWebUI and update `.env`.
### Step 3: Verify via Browser Subagent (Verify)
Use the `browser_subagent` tool. **You must fill in the `[Dynamic Content]` slots based on Step 1**:
```text
Task:
1. Access The Fixed URL: http://localhost:3003/?model=github_copilot_official_sdk_pipe.github_copilot_sdk-gpt-4.1
2. RELIABILITY WAIT: Wait until the page fully loads. Wait until the chat input text area (`#chat-input`) is present in the DOM.
3. ACTION - FAST INPUT: Use the `execute_browser_javascript` tool to instantly inject the query and submit it. Use exactly this script format to ensure stability:
`const input = document.getElementById('chat-input'); input.value = "[YOUR_DYNAMIC_TEST_PROMPT]"; input.dispatchEvent(new Event('input', { bubbles: true })); const e = new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true }); input.dispatchEvent(e);`
4. WAITING: Wait patiently for the streaming response to stop completely. You should wait for the Stop button to disappear, or wait for the system to settle (approximately 10-15 seconds depending on the query).
5. CHECK THE OUTCOME: [List the phenomena you expect to see, e.g., status bar shows specific text, tool card appears, result contains specific keywords, etc.]
6. CAPTURE: Take a screenshot of the settled state to prove the outcome.
7. REPORT: Report the EXACT outcome matching the criteria from step 5.
```
### Step 4: Evaluate & Iterate (Evaluate)
- **PASS**: Screenshot and phenomena match expectations. Report success to the user.
- **FAIL**: Analyze the issue based on screenshots/logs (e.g., race condition reappeared, API error). Modify the code and **re-run the entire skill workflow**.

View File

@@ -4,7 +4,7 @@ description: OpenWebUI Plugin Development & Release Workflow
# OpenWebUI Plugin Development Workflow
This workflow outlines the standard process for developing, documenting, and releasing plugins for OpenWebUI, ensuring compliance with project standards and CI/CD requirements.
This workflow outlines the standard process for developing, documenting, and releasing plugins for OpenWebUI. **Crucially, the default goal of this workflow is "Preparation" (updating all relevant files) rather than automatic "Submission" (git commit/push), unless a release is explicitly requested.**
## 1. Development Standards
@@ -12,11 +12,11 @@ Reference: `.github/copilot-instructions.md`
### Bilingual Requirement
Every plugin **MUST** have bilingual versions for both code and documentation:
Every plugin **MUST** have a single internationalized code file and bilingual documentation:
- **Code**:
- English: `plugins/{type}/{name}/{name}.py`
- Chinese: `plugins/{type}/{name}/{name_cn}.py` (or `中文名.py`)
- **Code (i18n)**:
- `plugins/{type}/{name}/{name}.py`
- The single `.py` file must implement internal i18n (e.g., using `navigator.language` or backend headers) to support multiple languages natively, rather than splitting into separate files.
- **README**:
- English: `plugins/{type}/{name}/README.md`
- Chinese: `plugins/{type}/{name}/README_CN.md`
@@ -45,8 +45,12 @@ When adding or updating a plugin, you **MUST** update the following documentatio
### Plugin Directory
- `README.md`: Update version, description, and usage. **Explicitly describe new features in a prominent position at the beginning.**
- `README_CN.md`: Update version, description, and usage. **Explicitly describe new features in a prominent position at the beginning.**
- `README.md`: Update version, description, and usage.
- **Key Capabilities**: **MUST** include ALL core functionalities and features. This is a cumulative section. Every release **MUST** verify that basic core descriptions are NOT lost or overwritten by new feature lists.
- **What's New**: Explicitly describe only the latest changes/updates in a prominent position at the beginning. This section is dynamic and changes with versions.
- `README_CN.md`: Update version, description, and usage.
- **核心功能 (Key Capabilities)**: **必须**包含所有核心功能和特性。这是一个累积性的部分,每次版本更新**必须**确认基础核心功能的描述没有丢失或被新功能列表覆盖。
- **最新更新 (What's New)**: 在开头显眼位置明确描述最新的更改/更新。此部分是动态的,随版本变化。
### Global Documentation (`docs/`)
@@ -73,16 +77,17 @@ Reference: `.github/workflows/release.yml`
- **When to Bump**: Only update the version when:
- User says "发布" / "release" / "bump version"
- User explicitly asks to prepare for release
- **Agent Initiative**: After completing significant changes (new features, bug fixes, or multiple code modifications), the agent **SHOULD proactively ask** the user if they want to release a new version. If confirmed, update all version-related files.
- **Agent Initiative**: After completing significant changes (new features, bug fixes, or multiple code modifications), the agent **SHOULD proactively ask** the user if they want to **prepare a new version** for release.
- **Release Information Compliance**: When a release is requested, the agent must generate a standard release summary (English commit title + bilingual bullet points) as defined in Section 3 & 5.
- **Default Action (Prepare Only)**: When performing a version bump or update, the agent should update all files locally but **STOP** before committing. Present the changes and the **proposed Release/Commit Message** to the user and wait for explicit confirmation to commit/push.
- **Consistency**: When bumping, update version in **ALL** locations:
1. English Code (`.py`)
2. Chinese Code (`.py`)
3. English README (`README.md`)
4. Chinese README (`README_CN.md`)
5. Docs Index (`docs/.../index.md`)
6. Docs Index CN (`docs/.../index.zh.md`)
7. Docs Detail (`docs/.../{name}.md`)
8. Docs Detail CN (`docs/.../{name}.zh.md`)
1. Code (`.py`)
2. English README (`README.md`)
3. Chinese README (`README_CN.md`)
4. Docs Index (`docs/.../index.md`)
5. Docs Index CN (`docs/.../index.zh.md`)
6. Docs Detail (`docs/.../{name}.md`)
7. Docs Detail CN (`docs/.../{name}.zh.md`)
### Automated Release Process
@@ -99,8 +104,23 @@ Reference: `.github/workflows/release.yml`
- **Auto-Sync**: If a local plugin has no ID but matches an existing published plugin by **Title**, the script will automatically fetch the ID, update the local file, and proceed with the update.
- Requirement: `OPENWEBUI_API_KEY` secret must be set.
- **README Link**: When announcing a release, always include the GitHub README URL for the plugin:
- Format: `https://github.com/Fu-Jie/awesome-openwebui/blob/main/plugins/{type}/{name}/README.md`
- Example: `https://github.com/Fu-Jie/awesome-openwebui/blob/main/plugins/filters/folder-memory/README.md`
- Format: `https://github.com/Fu-Jie/openwebui-extensions/blob/main/plugins/{type}/{name}/README.md`
- Example: `https://github.com/Fu-Jie/openwebui-extensions/blob/main/plugins/filters/folder-memory/README.md`
### Release Content Standard
When the user confirms a release, the agent **MUST** follow these content standards:
1. **Commit Message**:
- **Language**: English ONLY.
- **Format**: `type(scope): description` (e.g., `feat(pipes): add streaming support for Copilot SDK`).
- **Body**: List 1-3 key changes in bullet points.
2. **Release Summary (for user review)**:
- Before committing, present a "Release Draft" containing:
- **Title**: e.g., `Release v0.1.1: [Plugin Name] - [Brief Summary]`
- **Changelog**: English-only list of commits since the last release, including hashes (e.g., `896de02 docs(config): reorder antigravity model alias example`).
- **Verification Status**: Confirm all 7+ files have been updated and synced.
3. **Internal Documentation**: Ensure "What's New" sections in READMEs and `docs/` match exactly the changes being released.
### Pull Request Check
@@ -113,13 +133,17 @@ Reference: `.github/workflows/release.yml`
Before committing:
- [ ] Code is bilingual and functional?
- [ ] Code is internal i18n supported (`.py`) and fully functional?
- [ ] Docstrings have updated version?
- [ ] READMEs are updated and bilingual?
- [ ] **Key Capabilities** in READMEs still cover all legacy core features + new features?
- [ ] `docs/` index and detail pages are updated?
- [ ] Root `README.md` is updated?
- [ ] All version numbers match exactly?
## 5. Git Operations (Agent Rules)
Strictly follow the rules defined in `.github/copilot-instructions.md`**Git Operations (Agent Rules)** section.
1. **Prepare-on-Demand**: Focus on file modifications and local verification first.
2. **No Auto-Commit**: Never `git commit`, `git push`, or `create_pull_request` automatically after file updates unless the user explicitly says "commit this" or "release now".
3. **Draft Mode**: If available, use PRs as drafts first.
4. **Reference**: Strictly follow the rules defined in `.github/copilot-instructions.md`**Git Operations (Agent Rules)** section.

View File

@@ -45,12 +45,21 @@
"contributions": [
"ideas"
]
},
{
"login": "abaroni",
"name": "Alessandro Baroni",
"avatar_url": "https://avatars.githubusercontent.com/u/21365486?v=4",
"profile": "https://github.com/abaroni",
"contributions": [
"ideas"
]
}
],
"contributorsPerLine": 7,
"skipCi": true,
"repoType": "github",
"repoHost": "https://github.com",
"projectName": "awesome-openwebui",
"projectName": "openwebui-extensions",
"projectOwner": "Fu-Jie"
}
}

71
.gemini/skills/README.md Normal file
View File

@@ -0,0 +1,71 @@
# Agent Skills Index
This folder contains reusable Agent Skills for GitHub Copilot / VS Code custom agent workflows.
## Available Skills
- **community-announcer**
- Purpose: Generate community announcement content and related assets.
- Entry: `community-announcer/SKILL.md`
- **doc-mirror-sync**
- Purpose: Sync mirrored documentation content and helper scripts.
- Entry: `doc-mirror-sync/SKILL.md`
- **gh-issue-replier**
- Purpose: Draft standardized issue replies with templates.
- Entry: `gh-issue-replier/SKILL.md`
- **gh-issue-scheduler**
- Purpose: Schedule and discover unanswered issues for follow-up.
- Entry: `gh-issue-scheduler/SKILL.md`
- **i18n-validator**
- Purpose: Validate translation key consistency across i18n dictionaries.
- Entry: `i18n-validator/SKILL.md`
- **plugin-scaffolder**
- Purpose: Scaffold OpenWebUI plugin boilerplate with repository standards.
- Entry: `plugin-scaffolder/SKILL.md`
- **version-bumper**
- Purpose: Assist with semantic version bumping workflows.
- Entry: `version-bumper/SKILL.md`
- **xlsx-single-file**
- Purpose: Single-file spreadsheet operations workflow without LibreOffice.
- Entry: `xlsx-single-file/SKILL.md`
---
## Release Pipeline Skills
These four skills form a complete release pipeline and are designed to be used in sequence:
```
release-prep → pr-submitter → pr-reviewer → release-finalizer
(prepare) (push & PR) (respond to review) (merge & close issue)
```
- **release-prep**
- Purpose: Full release preparation — version sync across 7+ files, bilingual release notes creation, consistency check, and commit.
- Entry: `release-prep/SKILL.md`
- **pr-submitter**
- Purpose: Shell-escape-safe PR submission — writes body to temp file, validates sections, pushes branch, creates PR via `gh pr create --body-file`.
- Entry: `pr-submitter/SKILL.md`
- **pr-reviewer**
- Purpose: Fetch PR review comments, categorize feedback, implement fixes, commit and push, reply to reviewers.
- Entry: `pr-reviewer/SKILL.md`
- **release-finalizer**
- Purpose: Merge release PR to main with proper commit message, auto-link and close related issues, post closing messages.
- Entry: `release-finalizer/SKILL.md`
## Notes
- Skill definitions follow the expected location pattern:
- `.github/skills/<skill-name>/SKILL.md`
- Each skill may include optional `assets/`, `references/`, and `scripts/` folders.
- This directory mirrors `.gemini/skills` for compatibility.

View File

@@ -0,0 +1,23 @@
---
name: community-announcer
description: Drafts engaging English and Chinese update announcements for the OpenWebUI Community and other social platforms. Use when a new version is released.
---
# Community Announcer
## Overview
Automates the drafting of high-impact update announcements.
## Workflow
1. **Source Intel**: Read the latest version's `What's New` section from `README.md`.
2. **Drafting**: Create two versions:
- **Community Post**: Professional, structured, technical.
- **Catchy Short**: For Discord/Twitter, use emojis and bullet points.
3. **Multi-language**: Generate BOTH English and Chinese versions automatically.
## Announcement Structure (Recommended)
- **Headline**: "Update vX.X.X - [Main Feature]"
- **Introduction**: Brief context.
- **Key Highlights**: Bulleted list of fixes/features.
- **Action**: "Download from [Market Link]"
- **Closing**: Thanks and Star request.

View File

@@ -0,0 +1,14 @@
---
name: doc-mirror-sync
description: Automatically synchronizes plugin READMEs to the official documentation directory (docs/). Use after editing a plugin's local documentation to keep the MkDocs site up to date.
---
# Doc Mirror Sync
## Overview
Automates the mirroring of `plugins/{type}/{name}/README.md` to `docs/plugins/{type}/{name}.md`.
## Workflow
1. Identify changed READMEs.
2. Copy content to corresponding mirror paths.
3. Update version badges in `docs/plugins/{type}/index.md`.

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python3
import os
import shutil
import re
def sync_mirrors():
plugins_root = "plugins"
docs_root = "docs/plugins"
types = ["actions", "filters", "pipes", "pipelines", "tools"]
for t in types:
src_type_dir = os.path.join(plugins_root, t)
dest_type_dir = os.path.join(docs_root, t)
if not os.path.exists(src_type_dir): continue
os.makedirs(dest_type_dir, exist_ok=True)
for name in os.listdir(src_type_dir):
plugin_dir = os.path.join(src_type_dir, name)
if not os.path.isdir(plugin_dir): continue
# Sync README.md -> docs/plugins/{type}/{name}.md
src_readme = os.path.join(plugin_dir, "README.md")
if os.path.exists(src_readme):
dest_readme = os.path.join(dest_type_dir, f"{name}.md")
shutil.copy(src_readme, dest_readme)
print(f"✅ Mirrored: {t}/{name} (EN)")
# Sync README_CN.md -> docs/plugins/{type}/{name}.zh.md
src_readme_cn = os.path.join(plugin_dir, "README_CN.md")
if os.path.exists(src_readme_cn):
dest_readme_zh = os.path.join(dest_type_dir, f"{name}.zh.md")
shutil.copy(src_readme_cn, dest_readme_zh)
print(f"✅ Mirrored: {t}/{name} (ZH)")
if __name__ == "__main__":
sync_mirrors()

View File

@@ -0,0 +1,51 @@
---
name: gh-issue-replier
description: Professional English replier for GitHub issues. Use when a task is completed, a bug is fixed, or more info is needed from the user. Automates replying using the 'gh' CLI tool.
---
# Gh Issue Replier
## Overview
The `gh-issue-replier` skill enables Gemini CLI to interact with GitHub issues professionally. It enforces English for all communications and leverages the `gh` CLI to post comments.
## Workflow
1. **Identify the Issue**: Find the issue number (e.g., #49).
2. **Check Star Status**: Run the bundled script to check if the author has starred the repo.
* Command: `bash scripts/check_star.sh <issue-number>`
* Interpretation:
* Exit code **0**: User has starred. Use "Already Starred" templates.
* Exit code **1**: User has NOT starred. Include "Star Request" in the reply.
3. **Select a Template**: Load [templates.md](references/templates.md) to choose a suitable English response pattern.
4. **Draft the Reply**: Compose a concise message based on the star status.
5. **Post the Comment**: Use the `gh` tool to submit the reply.
## Tool Integration
### Check Star Status
```bash
bash scripts/check_star.sh <issue-number>
```
### Post Comment
```bash
gh issue comment <issue-number> --body "<message-body>"
```
Example (if user has NOT starred):
```bash
gh issue comment 49 --body "This has been fixed in v1.2.7. If you find this helpful, a star on the repo would be much appreciated! ⭐"
```
Example (if user HAS starred):
```bash
gh issue comment 49 --body "This has been fixed in v1.2.7. Thanks for your support!"
```
## Guidelines
- **Language**: ALWAYS use English for the comment body, even if the system prompt or user conversation is in another language.
- **Tone**: Professional, helpful, and appreciative.
- **Precision**: When announcing a fix, mention the specific version or the logic change (e.g., "Updated regex pattern").
- **Closing**: If the issue is resolved and you have permission, you can also use `gh issue close <number>`.

View File

@@ -0,0 +1,17 @@
# Reference Documentation for Gh Issue Replier
This is a placeholder for detailed reference documentation.
Replace with actual reference content or delete if not needed.
## Structure Suggestions
### API Reference Example
- Overview
- Authentication
- Endpoints with examples
- Error codes
### Workflow Guide Example
- Prerequisites
- Step-by-step instructions
- Best practices

View File

@@ -0,0 +1,45 @@
# Issue Reply Templates
Use these templates to craft professional English replies. Adjust placeholders like `@username`, `v1.2.x`, and `[commit hash]` as needed.
## 1. Acknowledging a New Issue
Use when you first see an issue and want to let the user know you are working on it.
- "Thank you for reporting this! I'm looking into it right now."
- "Thanks for bringing this to my attention. I'll try to reproduce this behavior and get back to you shortly."
## 2. Requesting More Information
Use when you need logs or specific details to fix the bug.
- "Could you please provide the **'Original'** vs **'Normalized'** content from your browser console logs (F12)? It would help a lot in debugging."
- "It would be very helpful if you could share the specific Markdown text that triggered this issue."
## 3. Announcing a Fix
Use when you have pushed the fix to the repository.
- "This has been fixed in version **v1.2.x**. You can update the plugin to resolve it."
- "I've just pushed a fix for this in [commit hash]. Please let me know if it works for you after updating."
- "The issue was caused by a greedy regex pattern. I've updated it to use a tempered greedy token to prevent incorrect merging."
## 4. Guiding to Official Market
Always provide the official market link to ensure the user gets the latest verified version.
- "The fix is now live! You can download the latest version from the official OpenWebUI Community page here: [Plugin Market Link]. Simply update the function in your OpenWebUI instance to apply the changes."
- "I recommend getting the updated version from the official store: [Link]. It includes the fix for the spacing issue we discussed."
## 5. Closing the Issue
Use when the issue is confirmed resolved.
- "Glad to hear it's working now! Closing this for now. Feel free to reopen it if the problem persists."
- "Since this is resolved, I'm closing this issue. Thanks again for your feedback!"
## 5. Pro-tip: Star Request
Gently handle star requests based on the user's current status.
### If User has NOT starred:
- "If you find this plugin helpful, a star on the repo would be much appreciated! ⭐"
- "We'd love your support! If this fixed your issue, please consider starring the repository. ⭐"
### If User HAS already starred:
- "Thanks again for starring the project and for your continuous support!"
- "I appreciate your support and for being a stargazer of this project!"

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Robust Star Checker v2
# Usage: ./check_star.sh <issue_number>
ISSUE_NUM=$1
if [ -z "$ISSUE_NUM" ]; then exit 2; fi
# 1. Get Repo and Author info
REPO_FULL=$(gh repo view --json owner,name -q ".owner.login + \"/\" + .name")
USER_LOGIN=$(gh issue view "$ISSUE_NUM" --json author -q ".author.login")
# 2. Use GraphQL for high precision (Detects stars even when REST 404s)
IS_STARRED=$(gh api graphql -f query='
query($owner:String!, $repo:String!, $user:String!) {
repository(owner:$owner, name:$repo) {
stargazers(query:$user, first:1) {
nodes {
login
}
}
}
}' -f owner="${REPO_FULL%/*}" -f repo="${REPO_FULL#*/}" -f user="$USER_LOGIN" -q ".data.repository.stargazers.nodes[0].login")
if [ "$IS_STARRED" == "$USER_LOGIN" ]; then
echo "Confirmed: @$USER_LOGIN HAS starred $REPO_FULL. ⭐"
exit 0
else
echo "Confirmed: @$USER_LOGIN has NOT starred $REPO_FULL."
exit 1
fi

View File

@@ -0,0 +1,42 @@
---
name: gh-issue-scheduler
description: Finds all open GitHub issues that haven't been replied to by the owner, summarizes them, and generates a solution plan. Use when the user wants to audit pending tasks or plan maintenance work.
---
# Gh Issue Scheduler
## Overview
The `gh-issue-scheduler` skill helps maintainers track community feedback by identifying unaddressed issues and drafting actionable technical plans to resolve them.
## Workflow
1. **Identify Unanswered Issues**: Run the bundled script to fetch issues without owner replies.
* Command: `bash scripts/find_unanswered.sh`
2. **Analyze and Summarize**: For each identified issue, summarize the core problem and the user's intent.
3. **Generate Solution Plans**: Draft a technical "Action Plan" for each issue, including:
* **Root Cause Analysis** (if possible)
* **Proposed Fix/Implementation**
* **Verification Strategy**
4. **Present to User**: Display a structured report of all pending issues and their respective plans.
## Tool Integration
### Find Unanswered Issues
```bash
bash scripts/find_unanswered.sh
```
## Report Format
When presenting the summary, use the following Markdown structure:
### 📋 Unanswered Issues Audit
#### Issue #[Number]: [Title]
- **Author**: @username
- **Summary**: Concise description of the problem.
- **Action Plan**:
1. Step 1 (e.g., Investigate file X)
2. Step 2 (e.g., Apply fix Y)
3. Verification (e.g., Run test Z)

View File

@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Fetch all open issues and filter for those without responses from the owner/collaborators.
# Uses 'gh' CLI.
REPO_FULL=$(gh repo view --json owner,name -q ".owner.login + "/" + .name")
OWNER=${REPO_FULL%/*}
# 1. Get all open issues
OPEN_ISSUES=$(gh issue list --state open --json number,title,author,createdAt --limit 100)
echo "Analysis for repository: $REPO_FULL"
echo "------------------------------------"
# Process each issue
echo "$OPEN_ISSUES" | jq -c '.[]' | while read -r issue; do
NUMBER=$(echo "$issue" | jq -r '.number')
TITLE=$(echo "$issue" | jq -r '.title')
AUTHOR=$(echo "$issue" | jq -r '.author.login')
# Check comments for owner responses
# We look for comments where the author is the repo owner
COMMENTS=$(gh issue view "$NUMBER" --json comments -q ".comments[].author.login" 2>/dev/null)
HAS_OWNER_REPLY=false
for COMMENT_AUTHOR in $COMMENTS; do
if [ "$COMMENT_AUTHOR" == "$OWNER" ]; then
HAS_OWNER_REPLY=true
break
fi
done
if [ "$HAS_OWNER_REPLY" == "false" ]; then
echo "ISSUE_START"
echo "ID: $NUMBER"
echo "Title: $TITLE"
echo "Author: $AUTHOR"
echo "Description:"
gh issue view "$NUMBER" --json body -q ".body"
echo "ISSUE_END"
fi
done

View File

@@ -0,0 +1,14 @@
---
name: i18n-validator
description: Validates multi-language consistency in the TRANSLATIONS dictionary of a plugin. Use to check if any language keys are missing or if translations need updating.
---
# I18n Validator
## Overview
Ensures all 12 supported languages (en-US, zh-CN, etc.) have aligned translation keys.
## Features
- Detects missing keys in non-English dictionaries.
- Suggests translations using the core AI engine.
- Validates the `fallback_map` for variant redirects.

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import sys
import ast
import os
def check_i18n(file_path):
if not os.path.exists(file_path):
print(f"Error: File not found {file_path}")
return
with open(file_path, 'r', encoding='utf-8') as f:
tree = ast.parse(f.read())
translations = {}
for node in tree.body:
if isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Name) and target.id == "TRANSLATIONS":
translations = ast.literal_eval(node.value)
break
if not translations:
print("⚠️ No TRANSLATIONS dictionary found.")
return
# Base keys from English
base_lang = "en-US"
if base_lang not in translations:
print(f"❌ Error: {base_lang} missing in TRANSLATIONS.")
return
base_keys = set(translations[base_lang].keys())
print(f"🔍 Analyzing {file_path}...")
print(f"Standard keys ({len(base_keys)}): {', '.join(sorted(base_keys))}
")
for lang, keys in translations.items():
if lang == base_lang: continue
lang_keys = set(keys.keys())
missing = base_keys - lang_keys
extra = lang_keys - base_keys
if missing:
print(f"{lang}: Missing {len(missing)} keys: {', '.join(missing)}")
if extra:
print(f"⚠️ {lang}: Has {len(extra)} extra keys: {', '.join(extra)}")
if not missing and not extra:
print(f"{lang}: Aligned.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: validate_i18n.py <path_to_plugin.py>")
sys.exit(1)
check_i18n(sys.argv[1])

View File

@@ -0,0 +1,59 @@
---
name: openwebui-community-publisher
description: Automatically publishes plugin update posts to openwebui.com.
---
# OpenWebUI Community Publisher
## Overview
This skill automates the process of creating **new** plugin release notes and announcements directly on the OpenWebUI Community (openwebui.com).
**Note**: This skill is exclusively for **new post creation**. Do NOT use this for updating existing posts, as updates are managed separately via dedicated scripts.
## Prerequisites
- User must be logged into [openwebui.com](https://openwebui.com) in the browser session.
- The content must be prepared in Markdown format (typically following the structure of the plugin's changelog or a dedicated release `.md` file).
## Execution Workflow
### 1. Verification
- Use `browser_subagent` to navigate to `https://openwebui.com`.
- Verify the logged-in user status (look for profile icons or "@Fu-Jie").
### 2. Post Creation
- Navigate to `https://openwebui.com/post`.
- **Post Type Selection**:
- Choose the appropriate tab based on content:
- **Text**: General announcements and documentation.
- **Tool**: Standalone tool plugins.
- **Function**: Pipes, Filters, or Actions.
- **Prompt**: Chat prompt templates.
- **Model**: GGUF/Ollama model files.
- Unless otherwise specified, default to **Text** for general release introductions.
- **Community Selection**:
- For general OpenWebUI related posts, select **o/openwebui**.
- For specialized topics, select the relevant community (e.g., **o/ollama** for models).
- **Metadata Mapping**:
- **Title**: Use the main header from the source file.
- **Content/Description**: Paste the Markdown body.
- **Source Code (for Function/Pipe)**: If publishing a `Function`, retrieve the corresponding `.py` file content and paste it into the code area.
- **Tags**: Leave empty by default unless relevant keywords are explicitly provided.
- **Media**: Optional, only attach if provided.
- **Settings**: Ensure "Adult content" is unchecked.
### 3. Submission & Validation
- Click the "Create" (创建) button.
- Wait for redirection to the final post URL.
- **CRITICAL**: Use `capture_browser_screenshot` to verify the rendering.
- Return the final URL to the user.
## Design Standards
- **Rich Aesthetics**: Use emojis in titles.
- **Structured Data**: Ensure tables and code blocks in the Markdown are preserved.
- **Internal Linking**: Link back to the OpenWebUI market or GitHub repository where applicable.

View File

@@ -0,0 +1,19 @@
---
name: plugin-scaffolder
description: Generates a standardized single-file i18n Python plugin template based on project standards. Use when starting a new plugin development to skip boilerplate writing.
---
# Plugin Scaffolder
## Overview
Generates compliant OpenWebUI plugin templates with built-in i18n, common utility methods, and required docstring fields.
## Usage
1. Provide the **Plugin Name** and **Type** (action/filter/pipe).
2. The skill will generate the `.py` file and the bilingual `README` files.
## Template Standard
- `Valves(BaseModel)` with `UPPER_SNAKE_CASE`
- `_get_user_context` with JS fallback and timeout
- `_emit_status` and `_emit_debug_log` methods
- Standardized docstring metadata

View File

@@ -0,0 +1,34 @@
# {{TITLE}}
**Author:** [Fu-Jie](https://github.com/Fu-Jie/openwebui-extensions) | **Version:** 0.1.0 | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT
{{DESCRIPTION}}
## 🔥 What's New in v0.1.0
* Initial release of {{TITLE}}.
## 🌐 Multilingual Support
Supports automatic interface and status switching for the following languages:
`English`, `简体中文`, `繁體中文 (香港)`, `繁體中文 (台灣)`, `한국어`, `日本語`, `Français`, `Deutsch`, `Español`, `Italiano`, `Tiếng Việt`, `Bahasa Indonesia`.
## ✨ Core Features
* Feature 1
* Feature 2
## How to Use 🛠️
1. Install the plugin in Open WebUI.
2. Configure settings in Valves.
## Configuration (Valves) ⚙️
| Parameter | Default | Description |
| :--- | :--- | :--- |
| `priority` | `50` | Execution priority. |
## ⭐ Support
If this plugin has been useful, a star on [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) is a big motivation for me. Thank you for the support.

View File

@@ -0,0 +1,80 @@
"""
title: {{TITLE}}
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
description: {{DESCRIPTION}}
"""
import asyncio
import logging
import json
from typing import Optional, Dict, Any, List, Callable, Awaitable
from pydantic import BaseModel, Field
from fastapi import Request
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
TRANSLATIONS = {
"en-US": {"status_starting": "Starting {{TITLE}}..."},
"zh-CN": {"status_starting": "正在启动 {{TITLE}}..."},
"zh-HK": {"status_starting": "正在啟動 {{TITLE}}..."},
"zh-TW": {"status_starting": "正在啟動 {{TITLE}}..."},
"ko-KR": {"status_starting": "{{TITLE}} 시작 중..."},
"ja-JP": {"status_starting": "{{TITLE}} を起動中..."},
"fr-FR": {"status_starting": "Démarrage de {{TITLE}}..."},
"de-DE": {"status_starting": "{{TITLE}} wird gestartet..."},
"es-ES": {"status_starting": "Iniciando {{TITLE}}..."},
"it-IT": {"status_starting": "Avvio di {{TITLE}}..."},
"vi-VN": {"status_starting": "Đang khởi động {{TITLE}}..."},
"id-ID": {"status_starting": "Memulai {{TITLE}}..."},
}
class {{CLASS_NAME}}:
class Valves(BaseModel):
priority: int = Field(default=50, description="Priority level (lower = earlier).")
show_status: bool = Field(default=True, description="Show status updates in UI.")
def __init__(self):
self.valves = self.Valves()
self.fallback_map = {
"zh": "zh-CN", "en": "en-US", "ko": "ko-KR", "ja": "ja-JP",
"fr": "fr-FR", "de": "de-DE", "es": "es-ES", "it": "it-IT",
"vi": "vi-VN", "id": "id-ID"
}
def _get_translation(self, lang: str, key: str, **kwargs) -> str:
target_lang = lang
if target_lang not in TRANSLATIONS:
base = target_lang.split("-")[0]
target_lang = self.fallback_map.get(base, "en-US")
lang_dict = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"])
text = lang_dict.get(key, TRANSLATIONS["en-US"].get(key, key))
return text.format(**kwargs) if kwargs else text
async def _get_user_context(self, __user__: Optional[dict], __event_call__: Optional[Callable] = None, __request__: Optional[Request] = None) -> dict:
user_data = __user__ if isinstance(__user__, dict) else {}
user_language = user_data.get("language", "en-US")
if __event_call__:
try:
js = "try { return (document.documentElement.lang || localStorage.getItem('locale') || navigator.language || 'en-US'); } catch (e) { return 'en-US'; }"
frontend_lang = await asyncio.wait_for(__event_call__({"type": "execute", "data": {"code": js}}), timeout=2.0)
if frontend_lang: user_language = frontend_lang
except: pass
return {"user_language": user_language}
async def {{METHOD_NAME}}(self, body: dict, __user__: Optional[dict] = None, __event_emitter__=None, __event_call__=None, __request__: Optional[Request] = None) -> dict:
if self.valves.show_status and __event_emitter__:
user_ctx = await self._get_user_context(__user__, __event_call__, __request__)
msg = self._get_translation(user_ctx["user_language"], "status_starting")
await __event_emitter__({"type": "status", "data": {"description": msg, "done": False}})
# Implement core logic here
if self.valves.show_status and __event_emitter__:
await __event_emitter__({"type": "status", "data": {"description": "Done", "done": True}})
return body

View File

@@ -0,0 +1,80 @@
"""
title: {{TITLE}}
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
description: {{DESCRIPTION}}
"""
import asyncio
import logging
import json
from typing import Optional, Dict, Any, List, Callable, Awaitable
from pydantic import BaseModel, Field
from fastapi import Request
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
TRANSLATIONS = {
"en-US": {"status_starting": "Starting {{TITLE}}..."},
"zh-CN": {"status_starting": "正在启动 {{TITLE}}..."},
"zh-HK": {"status_starting": "正在啟動 {{TITLE}}..."},
"zh-TW": {"status_starting": "正在啟動 {{TITLE}}..."},
"ko-KR": {"status_starting": "{{TITLE}} 시작 중..."},
"ja-JP": {"status_starting": "{{TITLE}} を起動中..."},
"fr-FR": {"status_starting": "Démarrage de {{TITLE}}..."},
"de-DE": {"status_starting": "{{TITLE}} wird gestartet..."},
"es-ES": {"status_starting": "Iniciando {{TITLE}}..."},
"it-IT": {"status_starting": "Avvio di {{TITLE}}..."},
"vi-VN": {"status_starting": "Đang khởi động {{TITLE}}..."},
"id-ID": {"status_starting": "Memulai {{TITLE}}..."},
}
class {{CLASS_NAME}}:
class Valves(BaseModel):
priority: int = Field(default=50, description="Priority level (lower = earlier).")
show_status: bool = Field(default=True, description="Show status updates in UI.")
def __init__(self):
self.valves = self.Valves()
self.fallback_map = {
"zh": "zh-CN", "en": "en-US", "ko": "ko-KR", "ja": "ja-JP",
"fr": "fr-FR", "de": "de-DE", "es": "es-ES", "it": "it-IT",
"vi": "vi-VN", "id": "id-ID"
}
def _get_translation(self, lang: str, key: str, **kwargs) -> str:
target_lang = lang
if target_lang not in TRANSLATIONS:
base = target_lang.split("-")[0]
target_lang = self.fallback_map.get(base, "en-US")
lang_dict = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"])
text = lang_dict.get(key, TRANSLATIONS["en-US"].get(key, key))
return text.format(**kwargs) if kwargs else text
async def _get_user_context(self, __user__: Optional[dict], __event_call__: Optional[Callable] = None, __request__: Optional[Request] = None) -> dict:
user_data = __user__ if isinstance(__user__, dict) else {}
user_language = user_data.get("language", "en-US")
if __event_call__:
try:
js = "try { return (document.documentElement.lang || localStorage.getItem('locale') || navigator.language || 'en-US'); } catch (e) { return 'en-US'; }"
frontend_lang = await asyncio.wait_for(__event_call__({"type": "execute", "data": {"code": js}}), timeout=2.0)
if frontend_lang: user_language = frontend_lang
except: pass
return {"user_language": user_language}
async def {{METHOD_NAME}}(self, body: dict, __user__: Optional[dict] = None, __event_emitter__=None, __event_call__=None, __request__: Optional[Request] = None) -> dict:
if self.valves.show_status and __event_emitter__:
user_ctx = await self._get_user_context(__user__, __event_call__, __request__)
msg = self._get_translation(user_ctx["user_language"], "status_starting")
await __event_emitter__({"type": "status", "data": {"description": msg, "done": False}})
# Implement core logic here
if self.valves.show_status and __event_emitter__:
await __event_emitter__({"type": "status", "data": {"description": "Done", "done": True}})
return body

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env python3
import sys
import os
def scaffold(p_type, p_name, title, desc):
target_dir = f"plugins/{p_type}/{p_name}"
os.makedirs(target_dir, exist_ok=True)
class_name = (
"Action"
if p_type == "actions"
else (
"Filter"
if p_type == "filters"
else "Tools" if p_type == "tools" else "Pipe"
)
)
method_name = (
"action"
if p_type == "actions"
else (
"outlet"
if p_type == "filters"
else "execute" if p_type == "tools" else "pipe"
)
)
replacements = {
"{{TITLE}}": title,
"{{DESCRIPTION}}": desc,
"{{CLASS_NAME}}": class_name,
"{{METHOD_NAME}}": method_name,
}
# Files to generate
templates = [
("assets/template.py.j2", f"{p_name}.py"),
("assets/README_template.md", "README.md"),
("assets/README_template.md", "README_CN.md"),
]
# Path relative to skill root
skill_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
for t_path, t_name in templates:
template_file = os.path.join(skill_root, t_path)
if not os.path.exists(template_file):
print(f"⚠️ Warning: Template not found {template_file}")
continue
with open(template_file, "r") as f:
content = f.read()
for k, v in replacements.items():
content = content.replace(k, v)
with open(os.path.join(target_dir, t_name), "w") as f:
f.write(content)
print(f"✅ Generated: {target_dir}/{t_name}")
if __name__ == "__main__":
if len(sys.argv) < 5:
print("Usage: scaffold.py <type> <name> <title> <desc>")
sys.exit(1)
scaffold(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

View File

@@ -0,0 +1,180 @@
---
name: pr-reviewer
description: Fetches PR review comments, analyzes requested changes, implements fixes, commits and pushes the resolution. Use after a reviewer has left comments on an open PR to close the feedback loop efficiently.
---
# PR Reviewer
## Overview
This skill automates the response cycle for code review. When a reviewer leaves comments on a Pull Request, this skill fetches all pending feedback, categorizes issues by severity, implements fixes, and submits a follow-up commit with appropriate review response comments.
## Prerequisites
- An open PR exists with pending review comments
- The local branch matches the PR's head branch
- `gh` CLI is authenticated
---
## Workflow
### Step 1 — Fetch Review State
Retrieve all review comments and overall review status:
```bash
# Get overall review decisions
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json reviews,reviewDecision,headRefName \
--jq '{decision: .reviewDecision, reviews: [.reviews[] | {author: .author.login, state: .state, body: .body}]}'
# Get inline code comments (specific line comments)
PAGER=cat GH_PAGER=cat gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/comments \
--jq '[.[] | {path: .path, line: .line, body: .body, author: .user.login, id: .id}]'
# Get general issue comments
PAGER=cat GH_PAGER=cat gh issue view <PR-NUMBER> --comments --json comments \
--jq '[.comments[] | {author: .author.login, body: .body}]'
```
Confirm the current local branch matches the PR head:
```bash
git branch --show-current
```
If mismatched, checkout the correct branch first.
### Step 2 — Categorize Review Feedback
Group feedback into categories:
| Category | Examples | Action |
|----------|---------|--------|
| **Code Bug** | Logic error, incorrect variable, broken condition | Fix code immediately |
| **Style / Formatting** | Indentation, naming convention, missing blank line | Fix code |
| **Documentation** | Missing i18n key, wrong version in README, typo | Fix docs |
| **Design Question** | Suggestion to restructure, alternative approach | Discuss with user before implementing |
| **Nitpick / Optional** | Minor style preferences reviewer marked as optional | Fix if quick; document if skipped |
| **Blocking** | Reviewer explicitly blocks merge | Must fix before proceeding |
Present the full categorized list to the user and confirm the resolution plan.
### Step 3 — Implement Fixes
For each accepted fix:
1. Read the affected file at the commented line for context:
```bash
sed -n '<line-5>,<line+10>p' <file-path>
```
2. Apply the fix using appropriate file edit tools
3. After editing, verify the specific area looks correct
**For code changes that might affect behavior:**
- Check if tests exist: `ls tests/test_*.py`
- If tests exist, run them: `python -m pytest tests/ -v`
**For documentation fixes:**
- If modifying README.md, check if `docs/` mirror needs the same fix
- Apply the same fix to both locations
### Step 4 — Run Consistency Checks
After all fixes are applied:
```bash
# Version consistency (if any version files were touched)
python3 scripts/check_version_consistency.py
# Quick syntax check for Python files
python3 -m py_compile plugins/{type}/{name}/{name}.py && echo "✅ Syntax OK"
```
### Step 5 — Stage and Commit
Create a new commit (do NOT amend if the branch has already been pushed, to avoid force-push):
```bash
git add -A
git status
```
Draft a Conventional Commits message for the fixup:
Format: `fix(scope): address review feedback`
Body should list what was fixed, referencing reviewer concerns:
```
fix(github-copilot-sdk): address review feedback from @reviewer
- Fix X per review comment on line Y of file Z
- Update README to clarify auth requirement
- Correct edge case in _parse_mcp_servers logic
```
```bash
git commit -m "<fixup commit message>"
```
### Step 6 — Push the Fix Commit
```bash
git push origin $(git branch --show-current)
```
**Force-push policy:**
- Use `git push` (non-force) by default
- Only use `git push --force-with-lease` if:
1. The user explicitly requests it, AND
2. The only change is an amended commit squash (cosmetic, no logic change)
3. Never use `--force` (without `--lease`)
### Step 7 — Respond to Reviewers
For each addressed review comment, post a reply:
```bash
# Reply to inline comment
gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/comments/<COMMENT-ID>/replies \
-X POST -f body="Fixed in commit <SHORT-SHA>. <Brief explanation of what was changed.>"
# General comment to summarize all fixes
gh issue comment <PR-NUMBER> --body "All review feedback addressed in commit <SHORT-SHA>:
- Fixed: <item 1>
- Fixed: <item 2>
Ready for re-review. 🙏"
```
### Step 8 — Re-Request Review (Optional)
If the reviewer had submitted a `CHANGES_REQUESTED` review, request a new review after fixes:
```bash
PAGER=cat GH_PAGER=cat gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/requested_reviewers \
-X POST -f reviewers[]='<reviewer-login>'
```
---
## Decision Guide
### When NOT to implement a suggestion immediately
- **Design questions**: "Should this be a separate class?" — Present to user for decision
- **Optional nitpicks**: Reviewer marked as `nit:` — Ask user if they want to include it
- **Large refactors**: If fix would require changing >50 lines, propose a separate follow-up issue instead
### When to ask the user before proceeding
- Any fix involving behavioral changes to plugin logic
- Renaming Valve keys (breaking change — requires migration notes)
- Changes that affect the bilingual release notes already committed
---
## Anti-Patterns to Avoid
- ❌ Do NOT `git commit --amend` on a pushed commit without user approval for force-push
- ❌ Do NOT silently skip a reviewer's comment; always acknowledge it (implement or explain why not)
- ❌ Do NOT use `--force` (only `--force-with-lease` when absolutely necessary)
- ❌ Do NOT make unrelated changes in the fixup commit; keep scope focused on review feedback
- ❌ Do NOT respond to reviewer comments in Chinese if the PR language context is English

View File

@@ -0,0 +1,179 @@
---
name: pr-submitter
description: Submits a feature branch as a Pull Request with a validated, properly formatted bilingual PR body. Handles shell-escape-safe body writing via temp files. Use after release-prep has committed all changes.
---
# PR Submitter
## Overview
This skill handles the final step of pushing a feature branch and creating a validated Pull Request on GitHub. Its primary purpose is to avoid the shell-escaping pitfalls (backticks, special characters in `gh pr create --body`) by always writing the PR body to a **temp file** first.
## Prerequisites
- All changes are committed (use `release-prep` skill first)
- The `gh` CLI is authenticated (`gh auth status`)
- Current branch is NOT `main` or `master`
---
## Workflow
### Step 1 — Pre-Flight Checks
Run these checks before any push:
```bash
# 1. Confirm not on protected branch
git branch --show-current
# 2. Verify there are commits to push
git log origin/$(git branch --show-current)..HEAD --oneline 2>/dev/null || echo "No remote tracking branch yet"
# 3. Check gh CLI auth
gh auth status
```
If any check fails, stop and report clearly.
### Step 2 — Collect PR Metadata
Gather:
- **PR Title**: Must follow Conventional Commits format, English only (e.g., `feat(github-copilot-sdk): release v0.8.0 with conditional tool filtering`)
- **Target base branch**: Default is `main`
- **Plugin name + version** (to build body sections)
- **Key changes** (reuse from release-prep or the latest What's New section)
### Step 3 — Build PR Body File (Shell-Escape-Safe)
**Always write the body to a temp file.** Never embed multi-line markdown with special characters directly in a shell command.
```bash
cat > /tmp/pr_body.md << 'HEREDOC'
## Summary
Brief one-sentence description of what this PR accomplishes.
## Changes
### New Features
- Feature 1 description
- Feature 2 description
### Bug Fixes
- Fix 1 description
## Plugin Version
- `PluginName` bumped to `vX.X.X`
## Documentation
- README.md / README_CN.md updated
- docs/ mirrors synced
## Testing
- [ ] Tested locally in OpenWebUI
- [ ] i18n validated (all language keys present)
- [ ] Version consistency check passed (`python3 scripts/check_version_consistency.py`)
---
## 变更摘要(中文)
简要描述本次 PR 的改动内容。
### 新功能
- 功能1描述
- 功能2描述
### 问题修复
- 修复1描述
HEREDOC
```
**Critical rules for the body file:**
- Use `<< 'HEREDOC'` (quoted heredoc) to prevent variable expansion
- Keep all backticks literal — they are safe inside a heredoc
- Paths like `/api/v1/files/` are safe too since heredoc doesn't interpret them as commands
### Step 4 — Validate PR Body
Before submitting, verify the body file contains expected sections:
```bash
# Check key sections exist
grep -q "## Summary" /tmp/pr_body.md && echo "✅ Summary" || echo "❌ Summary missing"
grep -q "## Changes" /tmp/pr_body.md && echo "✅ Changes" || echo "❌ Changes missing"
grep -q "## 变更摘要" /tmp/pr_body.md && echo "✅ CN Section" || echo "❌ CN Section missing"
# Preview the body
cat /tmp/pr_body.md
```
Ask the user to confirm the body content before proceeding.
### Step 5 — Push Branch
```bash
git push -u origin $(git branch --show-current)
```
If push is rejected (non-fast-forward), report to user and ask whether to force-push. **Do NOT force-push without explicit confirmation.**
### Step 6 — Create Pull Request
```bash
gh pr create \
--base main \
--head $(git branch --show-current) \
--title "<PR title from Step 2>" \
--body-file /tmp/pr_body.md
```
Always use `--body-file`, never `--body` with inline markdown.
### Step 7 — Verify PR Creation
```bash
PAGER=cat GH_PAGER=cat gh pr view --json number,url,title,body --jq '{number: .number, url: .url, title: .title, body_preview: .body[:200]}'
```
Confirm:
- PR number and URL
- Title matches intended Conventional Commits format
- Body preview includes key sections (not truncated/corrupted)
If the body appears corrupted (empty sections, missing backtick content), use edit:
```bash
gh pr edit <PR-NUMBER> --body-file /tmp/pr_body.md
```
### Step 8 — Cleanup
```bash
rm -f /tmp/pr_body.md
```
Report final PR URL to the user.
---
## Shell-Escape Safety Rules
| Risk | Safe Approach |
|------|--------------|
| Backticks in `--body` | Write to file, use `--body-file` |
| Paths like `/api/...` | Safe in heredoc; risky in inline `--body` |
| Newlines in `--body` | File-based only |
| `$variable` expansion | Use `<< 'HEREDOC'` (quoted) |
| Double quotes in body | Safe in heredoc file |
---
## Anti-Patterns to Avoid
- ❌ Never use `--body "..."` with multi-line content directly in shell command
- ❌ Never interpolate variables directly into heredoc without quoting the delimiter
- ❌ Never force-push (`--force`) without explicit user confirmation
- ❌ Never target `main` as the source branch (only as base)
- ❌ Never skip the body validation step — a PR with empty body is worse than a delayed PR

View File

@@ -0,0 +1,208 @@
---
name: release-finalizer
description: Merges a release PR, associates it with resolved issues, replies to issue reporters, and closes issues. Use after PR review is complete and ready for merge. Closes the release cycle.
---
# Release Finalizer
## Overview
This skill completes the final step of the release cycle: merging the release PR to `main`, replying to all related issues with solutions, and automatically closing them using GitHub's issue linking mechanism.
## Prerequisites
- The PR is in `OPEN` state and ready to merge
- All status checks have passed (CI green)
- All review feedback has been addressed
- The PR relates to one or more GitHub issues (either in PR description or through commits)
---
## Workflow
### Step 1 — Pre-Merge Verification
Verify that the PR is ready:
```bash
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json state,statusCheckRollup,reviewDecision
```
Checklist:
-`state` is `OPEN`
-`statusCheckRollup` all have `conclusion: SUCCESS`
-`reviewDecision` is `APPROVED` or empty (no blocking reviews)
If any check fails, **do NOT merge**. Report the issue to the user.
### Step 2 — Identify Related Issues
Issues can be linked to a PR in multiple ways. Check the PR description and commit messages for keywords:
```bash
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json body,commits
```
Look for patterns like:
- `Closes #XX`, `Fixes #XX`, `Resolves #XX` (in description or commit bodies)
- `#XX` mentioned as "related to" or "addresses"
**Manual input**: If issue links are not in the PR, ask the user which issue(s) this PR resolves.
Extract all issue numbers into a list: `[#48, #52, ...]`
### Step 3 — Select Merge Strategy
Offer the user three options:
| Strategy | Git Behavior | Use Case |
|----------|-------------|----------|
| **Squash** | All commits squashed into one commit on main | Clean history, recommended for release PRs |
| **Rebase** | Linear history, no merge commit | Preserve commit granularity |
| **Merge** | Merge commit created | Preserve full PR context |
**Recommendation for release PRs**: Use `--squash` to create a single clean commit.
If user doesn't specify, default to `--squash`.
### Step 4 — Prepare Merge Commit Message
If using `--squash`, craft a single comprehensive commit message:
**Format** (Conventional Commits + Github linking):
```
type(scope): description
- Bullet point 1
- Bullet point 2
Closes #48
Closes #52
```
The `Closes #XX` keyword tells GitHub to automatically close those issues when the commit lands on `main`.
Example:
```
feat(pipes,filters): release Copilot SDK Pipe v0.8.0 and Files Filter v0.1.3
- Implement P1~P4 conditional tool filtering system
- Fix file publishing reliability across all storage backends
- Add strict file URL validation
- Update bilingual documentation
Closes #48
```
### Step 5 — Execute Merge
```bash
gh pr merge <PR-NUMBER> \
--squash \
--delete-branch \
-m "type(scope): description" \
-b "- Bullet 1\n- Bullet 2\n\nCloses #48"
```
**Key flags:**
- `--squash`: Squash commits (recommended for releases)
- `--delete-branch`: Delete the feature branch after merge
- `-m`: Commit subject
- `-b`: Commit body (supports `\n` for newlines)
Confirm the merge is successful; GitHub will automatically close related issues with `Closes #XX` keyword.
### Step 6 — Verify Auto-Close
GitHub automatically closes issues when a commit with `Closes #XX` lands on the default branch (`main`).
To verify:
```bash
PAGER=cat GH_PAGER=cat gh issue view <ISSUE-NUMBER> --json state
```
Should show `state: CLOSED`.
### Step 7 — Post Closing Message (Optional but Recommended)
For better UX, manually post a summary comment to **each issue** before it auto-closes (since auto-close happens silently):
```bash
gh issue comment <ISSUE-NUMBER> --body "
This has been fixed in PR #<PR-NUMBER>, which is now merged to main.
**Solution Summary:**
- <Key fix 1>
- <Key fix 2>
The fix will be available in the next plugin release. Thank you for reporting! ⭐
"
```
### Step 8 — (Optional) Regenerate Release Notes
If the merge revealed any final tweaks to release notes:
```bash
# Re-export release notes from merged commit
git log --oneline -1 <merged-commit-sha>
```
If needed, create a follow-up PR with doc polish (do NOT force-push the merged commit).
---
## Merge Strategy Decision Tree
```
Is this a patch/hotfix release?
├─ YES → Use --squash
└─ NO → Multi-feature release?
├─ YES → Use --squash (cleaner history)
└─ NO → Preserve detail?
├─ YES → Use --rebase
└─ NO → Use --merge (preserve PR context)
```
---
## Issue Auto-Close Keywords
These keywords in commit/PR messages will auto-close issues when merged to `main`:
- `Closes #XX`
- `Fixes #XX`
- `Resolves #XX`
- `close #XX` (case-insensitive)
- `fix #XX`
- `resolve #XX`
**Important**: The keyword must be on the **final commit that lands on** `main`. For squash merges, it must be in the squash commit message body.
---
## Anti-Patterns to Avoid
- ❌ Do NOT merge if any status checks are PENDING or FAILED
- ❌ Do NOT merge if there are blocking reviews (reviewDecision: `CHANGES_REQUESTED`)
- ❌ Do NOT merge without verifying the Conventional Commits format in the merge message
- ❌ Do NOT merge without including `Closes #XX` keywords for all related issues
- ❌ Do NOT assume issues will auto-close silently — post a courtesy comment first
- ❌ Do NOT delete the branch if it might be needed for cherry-pick or hotfixes later
---
## Troubleshooting
### Issue did not auto-close after merge
- Verify the `Closes #XX` keyword is in the **final commit message** (use `git log` to check)
- Ensure the commit is on the `main` branch
- GitHub sometimes takes a few seconds to process; refresh the issue page
### Multiple issues to close
- List all in separate `Closes #XX` lines in the commit body
- Each one will be independently auto-closed
### Want to close issue without merge?
- Use `gh issue close <ISSUE-NUMBER>` manually
- Only recommended if the PR was manually reverted or deemed invalid

View File

@@ -0,0 +1,137 @@
---
name: release-prep
description: Orchestrates the full release preparation flow for a plugin — version sync across 7+ files, bilingual release notes creation, and commit message drafting. Use before submitting a PR. Does NOT push or create a PR; that is handled by pr-submitter.
---
# Release Prep
## Overview
This skill drives the complete pre-PR release pipeline. It enforces the repository rule that every release must synchronize the version number and changelog across **at least 7 locations** before a commit is created.
## Scope
This skill covers:
1. Version sync (delegates detail to `version-bumper` if needed)
2. Bilingual release notes file creation
3. 7-location consistency verification
4. Conventional Commits message drafting
5. `git add -A && git commit` execution
It **stops before** `git push` or `gh pr create`. Use the `pr-submitter` skill for those steps.
---
## Workflow
### Step 1 — Collect Release Info
Ask the user (or infer from current state) the following:
- **Plugin name** and **type** (actions / filters / pipes / tools)
- **New version number** (e.g., `0.8.0`)
- **Key changes** in English and Chinese (1-5 bullet points each)
If a `What's New` section already exists in README.md, extract it as the source of truth.
### Step 2 — Sync Version Across 7 Locations
Verify AND update the version string in all of the following. Mark each as ✅ or ❌:
| # | File | Location |
|---|------|----------|
| 1 | `plugins/{type}/{name}/{name}.py` | `version:` in docstring |
| 2 | `plugins/{type}/{name}/README.md` | `**Version:** x.x.x` metadata line |
| 3 | `plugins/{type}/{name}/README_CN.md` | `**Version:** x.x.x` metadata line |
| 4 | `docs/plugins/{type}/{name}.md` | `**Version:** x.x.x` metadata line |
| 5 | `docs/plugins/{type}/{name}.zh.md` | `**Version:** x.x.x` metadata line |
| 6 | `docs/plugins/{type}/index.md` | version badge for this plugin |
| 7 | `docs/plugins/{type}/index.zh.md` | version badge for this plugin |
Additionally update the root-level **updated date badge** in:
- `README.md``![updated](https://img.shields.io/badge/YYYY--MM--DD-gray?style=flat)`
- `README_CN.md` — same badge format
Use today's date (`YYYY-MM-DD`) for the badge.
### Step 3 — Update What's New (All 4 Doc Files)
The `What's New` / `最新更新` section must contain **only the most recent release's changes**. Previous entries should be removed from this section (they live in CHANGELOG or release notes files).
Update these 4 files' `What's New` / `最新更新` block consistently:
- `plugins/{type}/{name}/README.md`
- `plugins/{type}/{name}/README_CN.md`
- `docs/plugins/{type}/{name}.md`
- `docs/plugins/{type}/{name}.zh.md`
### Step 4 — Create Bilingual Release Notes Files
Create two versioned release notes files:
**Path**: `plugins/{type}/{name}/v{version}.md`
**Path**: `plugins/{type}/{name}/v{version}_CN.md`
#### Required Sections
Each file must include:
1. **Title**: `# v{version} Release Notes` (EN) / `# v{version} 版本发布说明` (CN)
2. **Overview**: One paragraph summarizing this release
3. **New Features** / **新功能**: Bulleted list of features
4. **Bug Fixes** / **问题修复**: Bulleted list of fixes
5. **Migration Notes** / **迁移说明**: Breaking changes or Valve key renames (omit section if none)
6. **Companion Plugins** / **配套插件** (optional): If a companion plugin was updated
If a release notes file already exists for this version, update it rather than creating a new one.
### Step 5 — Verify Consistency (Pre-Commit Check)
Run the consistency check script:
```bash
python3 scripts/check_version_consistency.py
```
If issues are found, fix them before proceeding. Do not commit with inconsistencies.
### Step 6 — Draft Conventional Commits Message
Generate the commit message following `commit-message.instructions.md` rules:
- **Language**: English ONLY
- **Format**: `type(scope): subject` + blank line + body bullets
- **Scope**: use plugin folder name (e.g., `github-copilot-sdk`)
- **Body**: 1-3 bullets summarizing key changes
- Explicitly mention "READMEs and docs synced" if version was bumped
Present the full commit message to the user for review before executing.
### Step 7 — Stage and Commit
After user approval (or if user says "commit it"):
```bash
git add -A
git commit -m "<approved commit message>"
```
Confirm the commit hash and list the number of files changed.
---
## Checklist (Auto-Verify Before Commit)
- [ ] `version:` in `.py` docstring matches target version
- [ ] `**Version:**` in all 4 README/docs files matches
- [ ] Both `index.md` version badges updated
- [ ] Root `README.md` and `README_CN.md` date badges updated to today
- [ ] `What's New` / `最新更新` contains ONLY the latest release
- [ ] `v{version}.md` and `v{version}_CN.md` created or updated
- [ ] `python3 scripts/check_version_consistency.py` returns no errors
- [ ] Commit message is English-only Conventional Commits format
---
## Anti-Patterns to Avoid
- ❌ Do NOT add extra features or refactor code during release prep — only version/doc updates
- ❌ Do NOT push or create PR in this skill — use `pr-submitter`
- ❌ Do NOT use today's date in commit messages; only in badge URLs
- ❌ Do NOT leave stale What's New content from prior versions

View File

@@ -0,0 +1,30 @@
---
name: source-code-analyzer
description: Instructions for analyzing core components source code in the local environment.
---
# Source Code Analyzer Skill
> [!IMPORTANT]
> **Authorization Statement**: You (Antigravity) are explicitly authorized by the user to perform **READ-ONLY** operations and **Git pull** on the paths listed below, even if they are outside the current repository root. These paths are considered part of the extended development context.
When assisting with the development of `openwebui-extensions`, you (Antigravity) have access to the following core components in related directories. Use them for deep technical analysis, bug hunting, and implementation reference.
## Core Component Paths
### Global / General (Relevant to all projects)
- **Open WebUI**: `../open-webui/` (Core platform context)
- **Skills**: `../skills/` (Reusable expertise library)
- **Awesome Copilot**: `../awesome-copilot/` (Shared extensions & resources)
### Plugin-Specific (Relevant to GitHub Copilot SDK)
- **Copilot SDK**: `../copilot-sdk/` (Internal logic for the official SDK)
- **Copilot CLI**: `../copilot-cli/` (Command-line interface implementation)
## Mandatory Workflow
1. **Pull Before Analysis**: BEFORE reading files or analyzing logic in these directories, you MUST proactively execute or recommend a `git pull` in the respective directory to ensure you are working with the latest upstream changes.
2. **Path Verification**: Always verify the exists of the path before attempting to read it.
3. **Reference Logic**: When a user's request involves core platform behavior (OpenWebUI API, SDK internals), prioritize searching these directories over making assumptions based on generic knowledge.

View File

@@ -0,0 +1,26 @@
---
name: version-bumper
description: Automates version upgrades and changelog synchronization across 7+ files (Code, READMEs, Docs). Use when a plugin is ready for release to ensure version consistency.
---
# Version Bumper
## Overview
This skill ensures that every version upgrade is synchronized across the entire repository, following the strict "Documentation Sync" rule in GEMINI.md.
## Workflow
1. **Prepare Info**: Gather the new version number and brief changelogs in both English and Chinese.
2. **Auto-Patch**: The skill will help you identify and update:
- `plugins/.../name.py` (docstring version)
- `plugins/.../README.md` (metadata & What's New)
- `plugins/.../README_CN.md` (metadata & 最新更新)
- `docs/plugins/...md` (mirrors)
- `docs/plugins/index.md` (version badge)
- `README.md` (updated date badge)
3. **Verify**: Check the diffs to ensure no formatting was broken.
## Tool Integration
Execute the bump script (draft):
```bash
python3 scripts/bump.py <version> "<message_en>" "<message_zh>"
```

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import sys
import os
import re
from datetime import datetime
def patch_file(file_path, old_pattern, new_content, is_regex=False):
if not os.path.exists(file_path):
print(f"Warning: File not found: {file_path}")
return False
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if is_regex:
new_content_result = re.sub(old_pattern, new_content, content, flags=re.MULTILINE)
else:
new_content_result = content.replace(old_pattern, new_content)
if new_content_result != content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_content_result)
print(f"✅ Patched: {file_path}")
return True
else:
print(f" No change needed: {file_path}")
return False
def bump_version(plugin_type, plugin_name, new_version, msg_en, msg_zh):
print(f"🚀 Bumping {plugin_name} ({plugin_type}) to {new_version}...")
today = datetime.now().strftime("%Y-%m-%d")
today_badge = today.replace("-", "--")
# 1. Patch Plugin Python File
py_file = f"plugins/{plugin_type}/{plugin_name}/{plugin_name}.py"
patch_file(py_file, r"version: \d+\.\d+\.\d+", f"version: {new_version}", is_regex=True)
# 2. Patch Plugin READMEs
readme_en = f"plugins/{plugin_type}/{plugin_name}/README.md"
readme_zh = f"plugins/{plugin_type}/{plugin_name}/README_CN.md"
# Update version in metadata
patch_file(readme_en, r"\*\*Version:\*\* \d+\.\d+\.\d+", f"**Version:** {new_version}", is_regex=True)
patch_file(readme_zh, r"\*\*版本:\*\* \d+\.\d+\.\d+", f"**版本:** {new_version}", is_regex=True)
# Update What's New (Assuming standard headers)
patch_file(readme_en, r"## 🔥 What's New in v.*?\n", f"## 🔥 What's New in v{new_version}\n\n* {msg_en}\n", is_regex=True)
patch_file(readme_zh, r"## 🔥 最新更新 v.*?\n", f"## 🔥 最新更新 v{new_version}\n\n* {msg_zh}\n", is_regex=True)
# 3. Patch Docs Mirrors
doc_en = f"docs/plugins/{plugin_type}/{plugin_name}.md"
doc_zh = f"docs/plugins/{plugin_type}/{plugin_name}.zh.md"
patch_file(doc_en, r"\*\*Version:\*\* \d+\.\d+\.\d+", f"**Version:** {new_version}", is_regex=True)
patch_file(doc_zh, r"\*\*版本:\*\* \d+\.\d+\.\d+", f"**版本:** {new_version}", is_regex=True)
# 4. Patch Root READMEs (Updated Date Badge)
patch_file("README.md", r"badge/202\d--\d\d--\d\d-gray", f"badge/{today_badge}-gray", is_regex=True)
patch_file("README_CN.md", r"badge/202\d--\d\d--\d\d-gray", f"badge/{today_badge}-gray", is_regex=True)
print("\n✨ All synchronization tasks completed.")
return True
if __name__ == "__main__":
if len(sys.argv) < 6:
print("Usage: bump.py <type> <name> <version> <msg_en> <msg_zh>")
print("Example: bump.py filters markdown_normalizer 1.2.8 'Fix bug' '修复错误'")
sys.exit(1)
bump_version(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])

121
.github/TEMP_FILES_POLICY.md vendored Normal file
View File

@@ -0,0 +1,121 @@
# Temporary Files Handling Policy
**Last Updated**: 2026-02-26
**Status**: Active Guideline
## Overview
All temporary files created during skill execution or development workflows must follow this centralized policy to maintain project cleanliness and workspace isolation alignment.
## Core Rule
**Temporary files MUST be stored in the project's `.temp/` directory, NOT in system directories like `/tmp`.**
## Rationale
1. **Workspace Isolation**: Aligns with OpenWebUI's workspace-per-user model
2. **Project Cohesion**: All project artifacts (temporary or permanent) stay within project boundaries
3. **Multi-User Safety**: Avoids conflicts between multiple developers using the same system
4. **Cleanup Traceability**: Easy to verify all temp files are cleaned up via single `.temp/` directory
5. **Debugging**: Inspectable before deletion if issues occur
## Usage Pattern
### Creating Temp File
```bash
# Step 1: Ensure temp directory exists
mkdir -p .temp
# Step 2: Write temp file
cat > .temp/my_temp_file.md << 'EOF'
...content...
EOF
# Step 3: Use the file in your workflow
# (e.g., pass to gh CLI, process with script, etc.)
```
### Cleanup After Use
```bash
# Remove individual temp files
rm -f .temp/my_temp_file.md
# Or full cleanup of entire temp directory
rm -rf .temp/
```
## Skills Affected
| Skill | Implementation | Status |
|-------|----------------|--------|
| `pr-submitter` | PR body file (`.temp/pr_body.md`) | ✅ Updated |
| `release-prep` | Draft notes (if any) | ✅ Policy Added |
| `version-bumper` | Backup files (if any) | Check needed |
| Future skills | TBD | 📋 Must follow policy |
## .gitignore Configuration
The following entry in `.gitignore` ensures temp files are never committed:
```
# Temporary files
.temp/
.build/
```
## Examples
### Example 1: PR Submitter Skill
```bash
# Create PR body in temp directory
mkdir -p .temp
cat > .temp/pr_body.md << 'EOF'
## Summary
New feature implementation
EOF
# Use with gh CLI
gh pr create --body-file .temp/pr_body.md --title "feat: new feature"
# Cleanup
rm -f .temp/pr_body.md
```
### Example 2: Release Prepare Workflow
```bash
# Create draft changelog
mkdir -p .temp
cat > .temp/changelog_draft.md << 'EOF'
# v1.0.0 Release Notes
EOF
# Edit, validate, then integrate into real files
# ...
# Cleanup
rm -f .temp/changelog_draft.md
```
## Anti-Patterns (❌ Don't Do This)
- ❌ Writing temp files to `/tmp` — will be lost/orphaned
- ❌ Writing to root directory or `plugins/` — pollutes repo
- ❌ Not cleaning up temp files — accumulates clutter
- ❌ Committing `.temp/` files to git — defeats the purpose
- ❌ Using absolute paths — breaks workflow portability
## Enforcement
1. **Code Review**: PRs should verify no `/tmp` references in scripts
2. **CI/CD**: Setup can validate `.temp/` cleanup via git status before commit
3. **Documentation**: All skill docs must reference this policy (link to this file)
4. **Automated**: Consider adding pre-commit hook to ensure `.temp/` is not staged
## Questions / Clarifications
For questions about this policy, refer to:
- `.github/skills/pr-submitter/SKILL.md` — Practical example
- `.github/skills/release-prep/SKILL.md` — Policy integration
- `/memories/repo/temp-file-handling-convention.md` — Internal notes

View File

@@ -0,0 +1,62 @@
---
name: Plugin Implementer
description: Implement OpenWebUI plugin and docs updates with strict project standards
argument-hint: Provide approved plan or feature request to implement
tools: ['execute/getTerminalOutput', 'execute/runInTerminal', 'read/readFile', 'read/terminalSelection', 'read/terminalLastCommand', 'edit/createFile', 'edit/editFiles', 'search', 'web', 'web/fetch', 'web/githubRepo', 'agent']
infer: true
handoffs:
- label: Run Review
agent: Plugin Reviewer
prompt: Review the implementation for i18n, safety, and consistency issues.
send: false
---
You are the **implementation specialist** for the `openwebui-extensions` repository.
## Execution Rules
1. **Minimal diffs**: Change only what the approved plan specifies.
2. **Single-file i18n**: Every plugin is one `.py` file with built-in `TRANSLATIONS` dict. Never create `_cn.py` split files.
3. **Context helpers**: Always use `_get_user_context(__user__)` and `_get_chat_context(body, __metadata__)` — never access dict keys directly.
4. **Emitter guards**: Every `await emitter(...)` must be guarded by `if emitter:`.
5. **Logging**: Use `logging.getLogger(__name__)` — no bare `print()` in production code.
6. **Async safety**: Wrap all `__event_call__` with `asyncio.wait_for(..., timeout=2.0)` + inner JS `try { ... } catch(e) { return fallback; }`.
## Required Plugin Pattern
```python
# Docstring: title, author, author_url, funding_url, version, description
# icon_url is REQUIRED for Action plugins (Lucide SVG, base64)
class Action: # or Filter / Pipe
class Valves(BaseModel):
SHOW_STATUS: bool = Field(default=True, description="...")
# All fields UPPER_SNAKE_CASE
def __init__(self):
self.valves = self.Valves()
def _get_user_context(self, __user__): ... # always implement
def _get_chat_context(self, body, __metadata__=None): ... # always implement
async def _emit_status(self, emitter, description, done=False): ...
async def _emit_notification(self, emitter, content, ntype="info"): ...
```
## Known Split-File Plugins (Legacy — Do NOT Add More)
These still have `_cn.py` files. When touching any of them, migrate CN content into `TRANSLATIONS` dict:
- `plugins/actions/deep-dive/deep_dive_cn.py`
- `plugins/actions/export_to_docx/export_to_word_cn.py`
- `plugins/actions/export_to_excel/export_to_excel_cn.py`
- `plugins/actions/flash-card/flash_card_cn.py`
- `plugins/actions/infographic/infographic_cn.py`
- `plugins/filters/folder-memory/folder_memory_cn.py`
## Version Bump Rule
Only bump version when user explicitly says "发布" / "release" / "bump version".
When bumping, update ALL 7+ files (code docstring + 2× README + 2× doc detail + 2× doc index + 2× root README date badge).
## Git Policy
- Never run `git commit`, `git push`, or create PRs automatically.
- After all edits, list what changed and why, then stop.
## Completion Output
- Modified files (full relative paths, one-line descriptions)
- Remaining manual checks
- Suggested handoff to **Plugin Reviewer**

78
.github/agents/plugin-planner.agent.md vendored Normal file
View File

@@ -0,0 +1,78 @@
---
name: Plugin Planner
description: Analyze requirements and produce a safe implementation plan for OpenWebUI plugins
argument-hint: Describe the plugin goal, constraints, and target files
tools: ['read/readFile', 'search', 'web', 'web/githubRepo', 'read/terminalLastCommand', 'read/terminalSelection', 'agent']
infer: true
handoffs:
- label: Start Implementation
agent: Plugin Implementer
prompt: Implement the approved plan step by step with minimal diffs.
send: false
---
You are the **planning specialist** for the `openwebui-extensions` repository.
## Your Responsibilities
1. Read existing plugin code and docs **before** proposing any change.
2. Produce a **small, reversible** plan (one logical change per file per step).
3. Clearly list all impacted files including the docs sync chain.
4. Flag risks: breaking changes, release implications, version bumps needed.
## Hard Rules
- Never propose `git commit`, `git push`, or PR creation.
- Every plan must end with an acceptance checklist for the user to approve before handing off.
- Reference `.github/copilot-instructions.md` as the authoritative spec.
## Repository Plugin Inventory
### Actions (`plugins/actions/`)
| Dir | Main file | Version | i18n status |
|-----|-----------|---------|-------------|
| `deep-dive` | `deep_dive.py` | 1.0.0 | ⚠️ has `deep_dive_cn.py` split |
| `export_to_docx` | `export_to_word.py` | 0.4.4 | ⚠️ has `export_to_word_cn.py` split |
| `export_to_excel` | `export_to_excel.py` | 0.3.7 | ⚠️ has `export_to_excel_cn.py` split |
| `flash-card` | `flash_card.py` | 0.2.4 | ⚠️ has `flash_card_cn.py` split |
| `infographic` | `infographic.py` | 1.5.0 | ⚠️ has `infographic_cn.py` split |
| `smart-mind-map` | `smart_mind_map.py` | 1.0.0 | ✅ single file |
| `smart-mermaid` | _(empty stub)_ | — | — |
### Filters (`plugins/filters/`)
| Dir | Main file | Version | i18n status |
|-----|-----------|---------|-------------|
| `async-context-compression` | `async_context_compression.py` | 1.3.0 | ✅ |
| `context_enhancement_filter` | `context_enhancement_filter.py` | 0.3 | ⚠️ non-SemVer version |
| `copilot_files_preprocessor` | _(empty stub)_ | — | — |
| `folder-memory` | `folder_memory.py` | 0.1.0 | ⚠️ has `folder_memory_cn.py` split |
| `github_copilot_sdk_files_filter` | `github_copilot_sdk_files_filter.py` | 0.1.2 | ✅ |
| `markdown_normalizer` | `markdown_normalizer.py` | 1.2.4 | ✅ |
| `web_gemini_multimodel_filter` | `web_gemini_multimodel.py` | 0.3.2 | ✅ |
### Pipes / Pipelines / Tools
| Path | Main file | Version |
|------|-----------|---------|
| `pipes/github-copilot-sdk` | `github_copilot_sdk.py` | 0.7.0 |
| `pipelines/moe_prompt_refiner` | `moe_prompt_refiner.py` | — |
| `tools/workspace-file-manager` | `workspace_file_manager.py` | 0.2.0 |
## Naming Conventions (Actual Mix)
- Action dirs: some use **dashes** (`deep-dive`, `flash-card`, `smart-mind-map`), some **underscores** (`export_to_docx`, `export_to_excel`, `infographic`)
- Filter dirs: similarly mixed — prefer underscores for new plugins
- Main `.py` filenames always use **underscores**
## Docs Sync Chain (for every plugin change)
For `plugins/{type}/{name}/`, these 7+ files must stay in sync:
1. `plugins/{type}/{name}/{name}.py` — version in docstring
2. `plugins/{type}/{name}/README.md` — version + What's New
3. `plugins/{type}/{name}/README_CN.md` — version + 最新更新
4. `docs/plugins/{type}/{name}.md`
5. `docs/plugins/{type}/{name}.zh.md`
6. `docs/plugins/{type}/index.md` — version badge
7. `docs/plugins/{type}/index.zh.md` — version badge
8. Root `README.md` / `README_CN.md` — date badge
## Output Format
- **Scope summary**
- **Affected files** (full relative paths)
- **Step-by-step plan** (numbered, ≤10 steps)
- **Risk flags** (version bump? breaking change? split-file migration needed?)
- **Acceptance checklist** → user must approve before handoff to Implementer

71
.github/agents/plugin-reviewer.agent.md vendored Normal file
View File

@@ -0,0 +1,71 @@
---
name: Plugin Reviewer
description: Perform strict repository-aligned code review for OpenWebUI plugin changes
argument-hint: Share changed files or branch diff to review
tools: ['search', 'read/readFile', 'web', 'web/fetch', 'web/githubRepo', 'execute/getTerminalOutput', 'read/terminalLastCommand', 'read/terminalSelection']
infer: true
handoffs:
- label: Prepare Release Draft
agent: Release Prep
prompt: Create a bilingual release draft and commit message based on reviewed changes.
send: false
---
You are the **review specialist** for the `openwebui-extensions` repository.
Full review rules are in .github/instructions/code-review.instructions.md.
## Review Checklist
### 🔴 Blocking (must fix before release)
**1. Single-file i18n Architecture**
- [ ] No new `_cn.py` split files created.
- [ ] All user-visible strings go through `TRANSLATIONS[lang].get(key, fallback)`.
- [ ] `FALLBACK_MAP` covers at least `zh → zh-CN` and `en → en-US`.
- [ ] `format(**kwargs)` on translations wrapped in `try/except KeyError`.
**2. Context Helpers**
- [ ] Uses `_get_user_context(__user__)` (not `__user__["name"]` directly).
- [ ] Uses `_get_chat_context(body, __metadata__)` (not ad-hoc `body.get("chat_id")`).
**3. Antigravity Safety**
- [ ] Every `__event_call__` wrapped: `asyncio.wait_for(..., timeout=2.0)`.
- [ ] JS code passed to `__event_call__` has `try { ... } catch(e) { return fallback; }`.
- [ ] File path operations validated against workspace root (no traversal).
- [ ] Upload paths have dual-channel fallback (API → DB/local).
**4. Emitter Guards**
- [ ] Every `await emitter(...)` guarded by `if emitter:`.
- [ ] `_emit_status(done=False)` on start, `done=True` on success, `_emit_notification("error")` on failure.
- [ ] No bare `print()` — use `logging.getLogger(__name__)`.
**5. Filter Singleton Safety**
- [ ] No mutable per-request state stored on `self` in Filter plugins.
**6. Streaming Compatibility (OpenWebUI 0.8.x)**
- [ ] `</think>` tag closed before any normal text or tool cards.
- [ ] `<details type="tool_calls" ...>` attributes escape `"` as `&quot;`.
- [ ] `<details ...>` block has newline immediately after `>`.
**7. Version & Docs Sync**
- [ ] Version bumped in docstring (if release).
- [ ] `README.md` + `README_CN.md` updated (What's New + version).
- [ ] `docs/plugins/{type}/{name}.md` and `.zh.md` match README.
- [ ] `docs/plugins/{type}/index.md` and `.zh.md` version badges updated.
- [ ] Root `README.md` / `README_CN.md` date badge updated.
### 🟡 Non-blocking (suggestions)
- Copilot SDK tools: `params_type=MyParams` in `define_tool()`.
- Long tasks (>3s): periodic `_emit_notification("info")` every 5s.
- `icon_url` present for Action plugins (Lucide SVG, base64).
## Known Pre-existing Issues (Don't block on unless the PR introduces new ones)
- `_cn.py` splits in: `deep-dive`, `export_to_docx`, `export_to_excel`, `flash-card`, `infographic`, `folder-memory` — legacy, not new.
- `context_enhancement_filter` version is `0.3` (non-SemVer) — pre-existing.
- `copilot_files_preprocessor` and `smart-mermaid` are empty stubs — pre-existing.
## Review Output
- **Blocking issues** (file:line references)
- **Non-blocking suggestions**
- **Pass / Fail verdict**
- **Next step**: Pass → handoff to Release Prep; Fail → return to Implementer with fix list

82
.github/agents/release-prep.agent.md vendored Normal file
View File

@@ -0,0 +1,82 @@
---
name: Release Prep
description: Prepare release-ready summaries and Conventional Commit drafts without pushing
argument-hint: Provide final change list and target version (optional)
tools: ['search', 'read/readFile', 'web', 'web/fetch', 'web/githubRepo', 'execute/getTerminalOutput', 'read/terminalLastCommand', 'read/terminalSelection']
infer: true
---
You are the **release preparation specialist** for the `openwebui-extensions` repository.
Full commit message rules: .github/instructions/commit-message.instructions.md
Full release workflow: .agent/workflows/plugin-development.md
## Responsibilities
1. Generate a Conventional Commit message (English only).
2. Draft bilingual release notes (EN + 中文).
3. Verify ALL file sync locations are updated.
4. **Stop before any commit or push** — wait for explicit user confirmation.
## Commit Message Format
```text
type(scope): brief imperative description
- Key change 1
- Key change 2 (include migration note if needed)
```
- `type`: `feat` / `fix` / `docs` / `refactor` / `chore`
- `scope`: plugin folder name (e.g., `smart-mind-map`, `github-copilot-sdk`, `folder-memory`)
- Title ≤ 72 chars, imperative mood, no trailing period, no capital first letter
## 9-File Sync Checklist (fill in for each changed plugin)
```text
Plugin: {type}/{name} → v{new_version}
[ ] 1. plugins/{type}/{name}/{name}.py → version in docstring
[ ] 2. plugins/{type}/{name}/README.md → version + What's New
[ ] 3. plugins/{type}/{name}/README_CN.md → version + 最新更新
[ ] 4. docs/plugins/{type}/{name}.md → mirrors README
[ ] 5. docs/plugins/{type}/{name}.zh.md → mirrors README_CN
[ ] 6. docs/plugins/{type}/index.md → version badge updated
[ ] 7. docs/plugins/{type}/index.zh.md → version badge updated
[ ] 8. README.md (root) → date badge updated
[ ] 9. README_CN.md (root) → date badge updated
```
## Current Plugin Versions (as of last audit — 2026-02-23)
| Plugin | Type | Version | Note |
|--------|------|---------|------|
| deep-dive | action | 1.0.0 | has `_cn.py` split |
| export_to_docx | action | 0.4.4 | has `_cn.py` split |
| export_to_excel | action | 0.3.7 | has `_cn.py` split |
| flash-card | action | 0.2.4 | has `_cn.py` split |
| infographic | action | 1.5.0 | has `_cn.py` split |
| smart-mind-map | action | 1.0.0 | ✅ |
| async-context-compression | filter | 1.3.0 | ✅ |
| context_enhancement_filter | filter | 0.3 | ⚠️ non-SemVer |
| folder-memory | filter | 0.1.0 | has `_cn.py` split |
| github_copilot_sdk_files_filter | filter | 0.1.2 | ✅ |
| markdown_normalizer | filter | 1.2.4 | ✅ |
| web_gemini_multimodel_filter | filter | 0.3.2 | ✅ |
| github-copilot-sdk | pipe | 0.7.0 | ✅ |
| workspace-file-manager | tool | 0.2.0 | ✅ |
## Output Template
### Commit Message
```text
{type}({scope}): {description}
- {change 1}
- {change 2}
```
### Change Summary (EN)
- {bullet list of user-visible changes}
### 变更摘要(中文)
- {中文要点列表}
### Verification Status
{filled-in 9-file checklist for each changed plugin}
---
⚠️ **Waiting for user confirmation — no git operations will run until explicitly approved.**

View File

@@ -1,4 +1,4 @@
# Copilot Instructions for awesome-openwebui
# Copilot Instructions for openwebui-extensions
本文档定义了 OpenWebUI 插件开发的标准规范和最佳实践。Copilot 在生成代码或文档时应遵循这些准则。
@@ -8,27 +8,26 @@ This document defines the standard conventions and best practices for OpenWebUI
## 🏗️ 项目结构与命名 (Project Structure & Naming)
### 1. 双语版本要求 (Bilingual Version Requirements)
### 1. 语言与代码规范 (Language & Code Requirements)
#### 插件代码 (Plugin Code)
每个插件必须提供两个版本:
每个插件**必须**采用单文件国际化 (i18n) 设计。严禁为不同语言创建独立的源代码文件(如 `_cn.py`)。
1. **英文版本**: `plugin_name.py` - 英文界面、提示词和注释
2. **中文版本**: `plugin_name_cn.py` - 中文界面、提示词和注释
1. **单代码文件**: `plugins/{type}/{name}/{name}.py`
2. **内置 i18n**: 必须在代码中根据前端传来的用户语言(如 `__user__` 中的 `language` 或通过 `get_user_language` 脚本读取)动态切换界面显示、提示词和状态日志。
示例:
示例目录结构
```
plugins/actions/export_to_docx/
├── export_to_word.py # English version
├── export_to_word_cn.py # Chinese version
── README.md # English documentation
└── README_CN.md # Chinese documentation
├── export_to_word.py # 单个代码文件,内置多语言支持
├── README.md # 英文文档 (English documentation)
── README_CN.md # 中文文档
```
#### 文档 (Documentation)
每个插件目录必须包含双语 README 文件:
尽管代码是合一的,但为了市场展示和 SEO每个插件目录仍**必须**包含双语 README 文件:
- `README.md` - English documentation
- `README_CN.md` - 中文文档
@@ -39,7 +38,7 @@ plugins/actions/export_to_docx/
1. **标题 (Title)**: 插件名称,带 Emoji 图标
2. **元数据 (Metadata)**: 作者、版本、项目链接 (一行显示)
- 格式: `**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** x.x.x | **Project:** [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui)`
- 格式: `**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** x.x.x | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions)`
- **注意**: Author 和 Project 为固定值,仅需更新 Version 版本号
3. **描述 (Description)**: 一句话功能介绍
4. **最新更新 (What's New)**: **必须**放在描述之后,仅展示**最近 1 次**更新
@@ -47,8 +46,8 @@ plugins/actions/export_to_docx/
6. **使用方法 (How to Use)**: 按步骤说明
7. **配置参数 (Configuration/Valves)**: 使用表格格式,包含参数名、默认值、描述
8. **支持 (Support)**: **必须**包含,放在配置参数之后、故障排除之前
- English: `If this plugin has been useful, a star on [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui) is a big motivation for me. Thank you for the support.`
- 中文: `如果这个插件对你有帮助,欢迎到 [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui) 点个 Star这将是我持续改进的动力感谢支持。`
- English: `If this plugin has been useful, a star on [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) is a big motivation for me. Thank you for the support.`
- 中文: `如果这个插件对你有帮助,欢迎到 [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) 点个 Star这将是我持续改进的动力感谢支持。`
9. **其他 (Others)**: 支持的模板类型、语法示例、故障排除等
- **Changelog**: 统一指向 GitHub 项目历史,不在 README 中列出具体变更
@@ -58,12 +57,10 @@ plugins/actions/export_to_docx/
plugins/
├── actions/ # Action 插件 (用户触发的功能)
│ ├── my_action/
│ │ ├── my_action.py # English version
│ │ ├── 我的动作.py # Chinese version
│ │ ├── my_action.py # 单文件,内置 i18n
│ │ ├── README.md # English documentation
│ │ └── README_CN.md # Chinese documentation
│ ├── ACTION_PLUGIN_TEMPLATE.py # English template
│ ├── ACTION_PLUGIN_TEMPLATE_CN.py # Chinese template
│ ├── ACTION_PLUGIN_TEMPLATE.py # 通用 i18n 模板
│ └── README.md
├── filters/ # Filter 插件 (输入处理)
│ └── ...
@@ -109,7 +106,7 @@ plugins/debug/
"""
title: 插件名称 (Plugin Name)
author: Fu-Jie
author_url: https://github.com/Fu-Jie/awesome-openwebui
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
icon_url: data:image/svg+xml;base64,<base64-encoded-svg>
@@ -124,7 +121,7 @@ description: 插件功能的简短描述。Brief description of plugin functiona
|--------------|---------------------|----------------|
| `title` | 插件显示名称 | `Export to Word` / `导出为 Word` |
| `author` | 作者名称 | `Fu-Jie` |
| `author_url` | 作者主页链接 | `https://github.com/Fu-Jie/awesome-openwebui` |
| `author_url` | 作者主页链接 | `https://github.com/Fu-Jie/openwebui-extensions` |
| `funding_url` | 赞助/项目链接 | `https://github.com/open-webui` |
| `version` | 语义化版本号 | `0.1.0`, `1.2.3` |
| `icon_url` | 图标 (Base64 编码的 SVG) | 仅 Action 插件**必须**提供。其他类型可选。 |
@@ -208,19 +205,56 @@ class Action:
#### 用户上下文 (User Context)
```python
def _get_user_context(self, __user__: Optional[Dict[str, Any]]) -> Dict[str, str]:
"""安全提取用户上下文信息。"""
if isinstance(__user__, (list, tuple)):
user_data = __user__[0] if __user__ else {}
elif isinstance(__user__, dict):
user_data = __user__
else:
user_data = {}
async def _get_user_context(
self,
__user__: Optional[dict],
__event_call__: Optional[callable] = None,
__request__: Optional[Request] = None,
) -> dict:
"""
Robust extraction of user context with multi-level fallback for language detection.
Priority: localStorage (via JS) > HTTP headers > User profile > en-US
"""
user_data = __user__ if isinstance(__user__, dict) else {}
user_id = user_data.get("id", "unknown_user")
user_name = user_data.get("name", "User")
user_language = user_data.get("language", "en-US")
# 1. Fallback: HTTP Accept-Language header
if __request__ and hasattr(__request__, "headers"):
accept_lang = __request__.headers.get("accept-language", "")
if accept_lang:
user_language = accept_lang.split(",")[0].split(";")[0]
# 2. Priority: Frontend localStorage via JS (requires timeout protection)
if __event_call__:
try:
js_code = """
try {
return (
document.documentElement.lang ||
localStorage.getItem('locale') ||
navigator.language ||
'en-US'
);
} catch (e) {
return 'en-US';
}
"""
# MUST use wait_for with timeout (e.g., 2.0s) to prevent backend deadlock
frontend_lang = await asyncio.wait_for(
__event_call__({"type": "execute", "data": {"code": js_code}}),
timeout=2.0
)
if frontend_lang and isinstance(frontend_lang, str):
user_language = frontend_lang
except Exception:
pass # Fallback to existing language
return {
"user_id": user_data.get("id", "unknown_user"),
"user_name": user_data.get("name", "User"),
"user_language": user_data.get("language", "en-US"),
"user_id": user_id,
"user_name": user_name,
"user_language": user_language,
}
```
@@ -474,13 +508,239 @@ async def get_user_language(self):
#### 适用场景与引导 (Usage Guidelines)
- **语言适配**: 动态获取界面语言 (`ru-RU`, `zh-CN`) 自动切换输出语言。
- **语言适配**: 动态获取界面语言 (`ru-RU`, `zh-CN`) 自动切换输出语言和 UI 翻译。这对于单文件 i18n 插件至关重要
- **时区处理**: 获取 `Intl.DateTimeFormat().resolvedOptions().timeZone` 处理时间。
- **客户端存储**: 读取 `localStorage` 中的用户偏好设置。
- **硬件能力**: 获取 `navigator.clipboard``navigator.geolocation` (需授权)。
**注意**: 即使插件有 `Valves` 配置,也应优先尝试自动探测,提升用户体验。
### 8. 国际化 (i18n) 适配规范 (Internationalization Standards)
开发供全球用户使用的插件时,必须预置多语言支持(如中文、英文等)。
#### i18n 字典定义
在文件顶部定义 `TRANSLATIONS` 字典存储多语言字符串:
```python
TRANSLATIONS = {
"en-US": {
"status_starting": "Smart Mind Map is starting...",
},
"zh-CN": {
"status_starting": "智能思维导图正在启动...",
},
# ... 其他语言
}
# 语言回退映射 (Fallback Map)
FALLBACK_MAP = {
"zh": "zh-CN",
"zh-TW": "zh-CN",
"zh-HK": "zh-CN",
"en": "en-US",
"en-GB": "en-US"
}
```
#### 获取当前用户真实语言 (Robust Language Detection)
Open WebUI 的前端localStorage并未自动同步语言设置到后端数据库或通过标准 API 参数传递。为了获取精准的用户偏好语言,**必须**使用多层级回退机制Multi-level Fallback
`JS 动态探测 (localStorage)` > `HTTP 浏览器头 (Accept-Language)` > `用户 Profile 默认设置` > `en-US`
> **注意!防卡死指南 (Anti-Deadlock Guide)**
> 在通过 `__event_call__` 执行前端 JS 脚本时,如果前端脚本不慎抛出异常 (`Exception`) 会导致回调函数 `cb()` 永不执行,这会让后端的 `asyncio` 永远阻塞并卡死整个请求队列!
> **必须**做两重防护:
> 1. JS 内部包裹 `try...catch` 保证必须有 `return`。
> 2. 后端使用 `asyncio.wait_for` 设置强制超时(建议 2 秒)。
```python
import asyncio
from fastapi import Request
async def _get_user_context(
self,
__user__: Optional[dict],
__event_call__: Optional[callable] = None,
__request__: Optional[Request] = None,
) -> dict:
user_language = __user__.get("language", "en-US") if __user__ else "en-US"
# 1st Fallback: HTTP Accept-Language header
if __request__ and hasattr(__request__, "headers") and "accept-language" in __request__.headers:
raw_lang = __request__.headers.get("accept-language", "")
if raw_lang:
user_language = raw_lang.split(",")[0].split(";")[0]
# 2nd Fallback (Best): Execute JS in frontend to read localStorage
if __event_call__:
try:
js_code = """
try {
return (
document.documentElement.lang ||
localStorage.getItem('locale') ||
navigator.language ||
'en-US'
);
} catch (e) {
return 'en-US';
}
"""
# 【致命!】必须设置 wait_for 防止前端无响应卡死后端
frontend_lang = await asyncio.wait_for(
__event_call__({"type": "execute", "data": {"code": js_code}}),
timeout=2.0
)
if frontend_lang and isinstance(frontend_lang, str):
user_language = frontend_lang
except Exception as e:
pass # fallback to accept-language or en-US
return {
"user_language": user_language,
# ... user_name, user_id etc.
}
```
#### 实际使用 (Usage in Action/Filter)
```python
async def action(self, body: dict, __user__: Optional[dict] = None, __event_call__: Optional[callable] = None, ...):
user_ctx = await self._get_user_context(__user__, __event_call__)
lang = user_ctx["user_language"]
# Use helper to get localized string with optional formatting
msg = self._get_translation(lang, "status_starting", name=user_ctx["user_name"])
await self._emit_status(emitter, msg)
```
#### 提示词中的语言一致性 (Language Consistency in Prompts)
在为 LLM 生成系统提示词时,必须包含“输出语言与输入保持一致”的指令,以确保 i18n 逻辑在 AI 生成环节也不断裂。
**标准指令示例**:
- `Language`: All output must be in the exact same language as the input text provided by the user.
- `Format Consistency`: Even if this system prompt is in English, if the user input is in Chinese, your output must be in Chinese.
#### CJK 脚本的特殊考量 (CJK Script Considerations)
当涉及字符长度限制(如思维导图标题、卡片摘要)时,应区分 CJK中日韩和拉丁脚本。
- **CJK (zh, ja, ko)**: 通常应设置更小的字符数限制(如 10 字以内)。
- **Latin (en, es, fr)**: 可设置较长的字符限制(如 5-8 个词或 35 字符)。
### 9. 智能代理文件交付规范 (Agent File Delivery Standards)
在开发具备文件生成能力的智能代理插件(如 GitHub Copilot SDK 集成)时,必须遵循以下标准流程,以确保文件在不同存储后端(本地/S3下的可用性并绕过不必要的 RAG 处理。
#### 核心协议:三步交付法 (The 3-Step Delivery Protocol)
1. **本地写入 (Write Local)**:
- 代理必须在当前执行目录 (`.`) 下创建文件。
- **严禁**使用系统临时目录(如 `/tmp`)存放待发布的文件,因为这些路径在隔离的工作空间外不可见。
2. **显式发布 (Publish)**:
- 必须调用内建工具 `publish_file_from_workspace(filename='name.ext')`
- 该工具负责将文件迁移至 Open WebUI 正式存储(自动适配 S3并注入 `skip_rag` 元数据以防止触发向量化流程RAG Bypass
3. **呈现链接 (Display Link)**:
- 获取工具返回的 `download_url`(正确格式为 `/api/v1/files/{id}/content`)。
- **必须**以 Markdown 链接形式(如 `[点击下载报告](url)`)展示给用户。
#### 路径语义 (Path Semantics)
- 代理应始终将“当前目录”视为其受保护所在的私有工作空间。
- `publish_file_from_workspace` 的参数 `filename` 仅需传入相对于当前目录的文件名。
### 10. Copilot SDK 插件工具定义规范 (Copilot SDK Tool Definition Standards)
在为 GitHub Copilot SDK 开发自定义工具时,为了确保大模型能正确识别参数(避免生成空的 `properties` Schema必须遵循以下定义模式
#### 显式参数模型 (Explicit Parameter Schema)
**禁止**仅依赖函数签名和类型提示。**必须**定义一个继承自 `pydantic.BaseModel` 的类来描述参数,并在 `define_tool` 中通过 `params_type` 显式引用。
```python
from pydantic import BaseModel, Field
from copilot import define_tool
# 1. 定义参数模型
class MyToolParams(BaseModel):
query: str = Field(..., description="搜索关键词")
limit: int = Field(default=10, description="返回结果数量限制")
# 2. 实现工具逻辑
async def my_custom_search(query: str, limit: int) -> dict:
# ... 逻辑实现 ...
return {"results": []}
# 3. 注册工具(关键:使用 params_type
my_tool = define_tool(
name="my_custom_search",
description="在特定数据源中执行搜索",
params_type=MyToolParams, # 显式传递参数模型以生成正确的 JSON Schema
)(my_custom_search)
```
#### 关键要点 (Key Requirements)
1. **params_type**: 必须在 `define_tool` 中使用此参数。这是防止大模型幻觉认为工具“无参数”的唯一可靠方法。
2. **Field 描述**: 在 `BaseModel` 中使用 `Field(..., description="...")` 为每个参数提供详细的描述信息。
3. **Required vs Optional**: 明确标注必填项(无默认值)和可选项(带 `default`)。
### 11. Copilot SDK 流式渲染与工具卡片规范 (Streaming & Tool Card Standards)
在处理大模型的思维链Reasoning输出和工具调用Tool Calls为了确保能完美兼容 OpenWebUI 0.8.x 前端的 Markdown 解析器及原生折叠 UI 组件,必须遵循以下极度严格的输出格式规范。
#### 思维链流式渲染 (Reasoning Streaming)
为了让前端能够正确显示“Thinking...”的折叠框和 Spinner 动画,**必须**使用原生的 `<think>` 标签。
- **正确的标签包裹**:
```html
<think>
这里是思考过程...
</think>
```
- **关键细节**:
- **标签闭合检测**: 必须在代码内部维护状态(如 `state["thinking_started"]`。当1正文内容即将开始输出2工具调用触发 (`tool.execution_start`) 时,**必须优先输出 `\n</think>\n` 强制闭合标签**。如果不闭合,后续的正文或工具面板会被全部吞进思考框内,导致页面完全崩坏!
- **不要手动拼装**: 严禁通过手动输出 `<details type="reasoning">` 等大段 HTML 来模拟思考过程,这种方式极易在流式片段发送中破坏前端 DOM 树并导致错位。
#### 工具调用原生卡片 (Native Tool Calls Block)
为了在对话界面中生成标准、原生的下拉折叠“工具调用”卡片,当 `event_type == "tool.execution_complete"` 时,必须向队列输出如下严格格式的 HTML
```python
# 必须转义属性中的双引号为 &quot;
args_for_attr = args_json_str.replace('"', "&quot;")
result_for_attr = result_content.replace('"', "&quot;")
tool_block = (
f'\\n<details type="tool_calls"'
f' id="{tool_call_id}"'
f' name="{tool_name}"'
f' arguments="{args_for_attr}"'
f' result="{result_for_attr}"'
f' done="true">\\n'
f"<summary>Tool Executed</summary>\\n"
f"</details>\\n\\n"
)
queue.put_nowait(tool_block)
```
- **致命避坑点 (Critical Pitfalls)**:
1. **属性转义 (Extremely Important)**: `<details>` 内的 `arguments` 和 `result` 属性**必须**将内部的所有双引号 `"` 替换为 `&quot;`。因为 OpenWebUI 前端提取这些数据的 Regex 是严格的 `="([^"]*)"`,一旦内容中出现原生双引号,就会被瞬间截断,导致参数被渲染为空并引发解析错误!
2. **换行符要求**: `<details ...>` 尖括号闭合后紧接着的内容**必须换行**(即 `>\\n`),否则 Markdown 扩展引擎无法将其识别为独立的 UI Block。
3. **去除冗余通知**: 不要在 `tool.execution_start` 事件中提前向对话流输出普通的 `🔧 Executing...` 纯文本块,这会导致最终页面上同时出现两块工具提示(一个文本,一个折叠卡片)。
#### Debug 信息的解耦 (Decoupling Debug Logs)
对于连接建立、运行环境、缓存加载等属于 *脚本自身运行状态* 的 Debug 信息:
- **禁止**: 不要将这些内容 yield 到最终的回答数据流(或塞进 `<think>` 标签内),这会污染回答的纯粹性。
- **推荐**: 统一使用 OpenWebUI 顶部的原生状态反馈气泡Status Events
```python
await __event_emitter__({
"type": "status",
"data": {"description": "连接建立,正在等待响应...", "done": True}
})
```
---
## ⚡ Action 插件规范 (Action Plugin Standards)
@@ -878,8 +1138,7 @@ Filter 实例是**单例 (Singleton)**。
### 1. ✅ 开发检查清单 (Development Checklist)
- [ ] 创建英文版插件代码 (`plugin_name.py`)
- [ ] 创建中文版插件代码 (`plugin_name_cn.py`)
- [ ] 代码实现了内置 i18n 逻辑 (`.py`)
- [ ] 编写英文 README (`README.md`)
- [ ] 编写中文 README (`README_CN.md`)
- [ ] 包含标准化文档字符串
@@ -887,15 +1146,20 @@ Filter 实例是**单例 (Singleton)**。
- [ ] 使用 Lucide 图标
- [ ] 实现 Valves 配置
- [ ] 使用 logging 而非 print
- [ ] 测试双语界面
- [ ] 测试 i18n 界面适配
- [ ] **一致性检查**: 确保文档、代码、README 同步
- [ ] **README 结构**:
- **Key Capabilities** (英文) / **核心功能** (中文): 必须包含所有核心功能
- **What's New** (英文) / **最新更新** (中文): 仅包含最新版本的变更信息
### 2. 🔄 一致性维护 (Consistency Maintenance)
任何插件的**新增、修改或移除**,必须同时更新:
1. **插件代码** (version)
2. **项目文档** (`docs/`)
3. **自述文件** (`README.md`)
2. **插件自述文件** (`plugins/{type}/{name}/README.md` & `README_CN.md`)
3. **项目文档** (`docs/plugins/{type}/{name}.md` & `.zh.md`)
4. **项目文档索引** (`docs/plugins/{type}/index.md` & `index.zh.md` — 版本号)
5. **项目根 README** (`README.md` & `README_CN.md` — 更新日期徽章 `![updated](https://img.shields.io/badge/YYYY--MM--DD-gray?style=flat)` 必须同步为发布当天日期)
### 3. 发布工作流 (Release Workflow)
@@ -925,10 +1189,20 @@ Filter 实例是**单例 (Singleton)**。
- Update README/README_CN to include What's New section
- Migration: default TITLE_SOURCE changed to chat_title
### 4. 🤖 Git Operations (Agent Rules)
#### 发布信息生成准则 (Release Summary Generation)
当准备提交时,必须向用户展示以下格式的“发布草案”:
1. **Commit Message**: 符合 Conventional Commits 的英文标题及摘要。
2. **变更列表 (Bilingual Changes)**:
- 英文: Clear descriptions of technical/functional changes.
- 中文: 清晰描述用户可见的功能改进或修复。
3. **核查状态 (Verification)**: 确认版本号已在相关 7+ 处位置同步更新1 个代码文件 + 2 个 README + 4 个 Docs 文件)。
- **允许**: 直接推送到 `main` 分支并发布。
- **允许**: 创建功能分支 (`feature/xxx`),推送到功能分支。
### 4. 🤖 Git 提交与推送规范 (Git Operations & Push Rules)
- **核心原则**: 默认仅进行**本地文件准备**更新代码、READMEs、Docs、版本号**严禁**在未获用户明确许可的情况下自动执行 `git commit` 或 `git push`。
- **允许 (需确认)**: 只有在用户明确表示“发布”、“Commit it”、“Release”或“提交”后才允许直接推送到 `main` 分支或创建 PR。
- **功能分支**: 推荐在进行大规模重构或实验性功能开发时,创建功能分支 (`feature/xxx`) 进行隔离。
- **PR 提交**: 必须使用 GitHub CLI (`gh`) 创建 Pull Request。示例`gh pr create --title "feat: ..." --body "..."`。
### 5. 🤝 贡献者认可规范 (Contributor Recognition)
@@ -938,8 +1212,7 @@ Filter 实例是**单例 (Singleton)**。
## 📚 参考资源 (Reference Resources)
- [Action 插件模板 (英文)](plugins/actions/ACTION_PLUGIN_TEMPLATE.py)
- [Action 插件模板 (中文)](plugins/actions/ACTION_PLUGIN_TEMPLATE_CN.py)
- [Action 插件模板](plugins/actions/ACTION_PLUGIN_TEMPLATE.py)
- [插件开发指南](plugins/actions/PLUGIN_DEVELOPMENT_GUIDE.md)
- [Lucide Icons](https://lucide.dev/icons/)
- [OpenWebUI 文档](https://docs.openwebui.com/)
@@ -949,8 +1222,9 @@ Filter 实例是**单例 (Singleton)**。
## Author
Fu-Jie
GitHub: [Fu-Jie/awesome-openwebui](https://github.com/Fu-Jie/awesome-openwebui)
GitHub: [Fu-Jie/openwebui-extensions](https://github.com/Fu-Jie/openwebui-extensions)
## License
MIT License
```

View File

@@ -0,0 +1,54 @@
---
name: Plugin Code Review
description: Comprehensive OpenWebUI plugin review checklist covering i18n, context helpers, antigravity safety, and streaming compatibility
applyTo: "plugins/**/*.py"
---
# Code Review Instructions — OpenWebUI Plugins
You are an expert Senior Software Engineer reviewing OpenWebUI plugins for the `openwebui-extensions` repository.
When reviewing plugin code, you MUST verify each point below to ensure the code meets the strict repository standards.
## 1. Single-file i18n Pattern (CRITICAL)
- **One File Rule**: One `.py` file per plugin. No `_cn.py` or language-split files.
- **Translations**: All user-visible strings (status, notification, UI text) MUST go through a `TRANSLATIONS` dictionary and a `FALLBACK_MAP`.
- **Safety**: `format(**kwargs)` calls on translated strings MUST be wrapped in `try/except KeyError` to prevent crashes if a translation is missing a placeholder.
## 2. Context Helpers (CRITICAL)
- **User Context**: MUST use `_get_user_context(__user__)` instead of direct `__user__["name"]` access. `__user__` can be a list, dict, or None.
- **Chat Context**: MUST use `_get_chat_context(body, __metadata__)` instead of ad-hoc `body.get("chat_id")` calls.
## 3. Event & Logging
- **No Print**: No bare `print()` in production code. Use `logging.getLogger(__name__)`.
- **Emitter Safety**: Every `await emitter(...)` call MUST be guarded by `if emitter:` (or equivalent).
- **Status Lifecycle**:
- `_emit_status(done=False)` at task start.
- `_emit_status(done=True)` on completion.
- `_emit_notification("error")` on failure.
## 4. Antigravity Safety (CRITICAL)
- **Timeout Guards**: All `__event_call__` JS executions MUST be wrapped with `asyncio.wait_for(..., timeout=2.0)`. Failure to do this can hang the entire backend.
- **JS Fallbacks**: JS code executed via `__event_call__` MUST have an internal `try { ... } catch (e) { return fallback; }` block.
- **Path Sandboxing**: File path operations MUST be validated against the workspace root (no directory traversal vulnerabilities).
- **Upload Fallbacks**: Upload paths MUST have a dual-channel fallback (API → local/DB).
## 5. Filter Singleton Safety
- **No Mutable State**: Filter plugins are singletons. There MUST be NO request-scoped mutable state stored on `self` (e.g., `self.current_user = ...`).
- **Statelessness**: Per-request values MUST be computed from `body` and context helpers on each call.
## 6. Copilot SDK Tools
- **Pydantic Models**: Tool parameters MUST be defined as a `pydantic.BaseModel` subclass.
- **Explicit Params**: `define_tool(...)` MUST include `params_type=MyParams`.
- **Naming**: Tool names MUST match `^[a-zA-Z0-9_-]+$` (ASCII only).
## 7. Streaming Compatibility (OpenWebUI 0.8.x)
- **Thinking Tags**: The `</think>` tag MUST be closed before any normal content or tool cards are emitted.
- **Attribute Escaping**: Tool card `arguments` and `result` attributes MUST escape `"` as `&quot;`.
- **Newline Requirement**: The `<details type="tool_calls" ...>` block MUST be followed by a newline immediately after `>`.
## 8. Performance & Memory
- **Streaming**: Large files or responses MUST be streamed, not loaded entirely into memory.
- **Database Connections**: Plugins MUST reuse the OpenWebUI internal database connection (`owui_engine`, `owui_Session`) rather than creating new ones.
## 9. HTML Injection (Action Plugins)
- **Wrapper Template**: HTML output MUST use the standard `<!-- OPENWEBUI_PLUGIN_OUTPUT -->` wrapper.
- **Idempotency**: The plugin MUST implement `_remove_existing_html` to ensure multiple runs do not duplicate the HTML output.

View File

@@ -0,0 +1,90 @@
---
name: Commit Message
description: Comprehensive Conventional Commits guidelines for openwebui-extensions
---
# Commit Message Instructions
You are an expert developer generating commit messages for the `openwebui-extensions` repository.
Always adhere to the following strict guidelines based on the Conventional Commits specification.
## 1. General Rules
- **Language**: **English ONLY**. Never use Chinese or other languages in the commit title or body.
- **Structure**:
```text
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
## 2. Type (`<type>`)
Must be one of the following:
- `feat`: A new feature or a new plugin.
- `fix`: A bug fix.
- `docs`: Documentation only changes (e.g., README, MkDocs).
- `refactor`: A code change that neither fixes a bug nor adds a feature.
- `perf`: A code change that improves performance.
- `test`: Adding missing tests or correcting existing tests.
- `chore`: Changes to the build process, CI/CD, or auxiliary tools/scripts.
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc.).
## 3. Scope (`<scope>`)
The scope should indicate the affected component or plugin.
- **For Plugins**: Use the plugin's folder name or category (e.g., `actions`, `filters`, `pipes`, `export-to-docx`, `github-copilot-sdk`).
- **For Docs**: Use `docs` or the specific doc section (e.g., `guide`, `readme`).
- **For Infra**: Use `ci`, `scripts`, `deps`.
- *Note*: Omit the scope if the change is global or spans too many components.
## 4. Subject Line (`<subject>`)
- **Length**: Keep it under 50-72 characters.
- **Mood**: Use the imperative, present tense: "change" not "changed" nor "changes" (e.g., "add feature" instead of "added feature").
- **Formatting**: Do not capitalize the first letter. Do not place a period `.` at the end.
- **Clarity**: State exactly *what* changed. Avoid vague terms like "update code" or "fix bug".
## 5. Body (`<body>`)
- **When to use**: Highly recommended for `feat`, `fix`, and `refactor`.
- **Content**: Explain *what* and *why* (motivation), not just *how* (the code diff shows the how).
- **Format**: Use a bulleted list (1-3 points) for readability.
- **Repo Specifics**: If the commit involves a plugin version bump, explicitly mention that the READMEs and docs were synced.
## 6. Footer / Breaking Changes (`<footer>`)
- If the commit introduces a breaking change (e.g., changing a Valve configuration key, altering a plugin's output format), append `!` after the scope/type: `feat(pipes)!: ...`
- Add a `BREAKING CHANGE:` block in the footer explaining the migration path.
## 7. Examples
**Example 1: Feature with Body**
```text
feat(github-copilot-sdk): add antigravity timeout guards
- Wrap all __event_call__ JS executions with asyncio.wait_for(timeout=2.0)
- Add dual-channel upload fallback (API → local/DB)
- Emit staged status events for tasks > 3 seconds
```
**Example 2: Bug Fix**
```text
fix(export-to-docx): resolve missing title fallback
- Fallback to user_name + date when chat_title is empty
- Prevent crash when metadata variables are missing
```
**Example 3: Documentation Sync**
```text
docs(plugins): sync bilingual READMEs for v1.2.0 release
- Update What's New section for folder-memory plugin
- Sync docs/plugins/filters/folder-memory.md
```
**Example 4: Breaking Change**
```text
refactor(core)!: rename global configuration valves
- Standardize all valve keys to UPPER_SNAKE_CASE
- Remove deprecated legacy_api_key field
BREAKING CHANGE: Users must reconfigure their API keys in the UI as the old `api_key` field is no longer read.
```

View File

@@ -0,0 +1,54 @@
---
name: Test Generation
description: Comprehensive Pytest conventions, mocking strategies, and model usage rules for OpenWebUI plugins
applyTo: "plugins/debug/**,tests/**"
---
# Test Generation Instructions
You are an expert SDET (Software Development Engineer in Test) writing tests for the `openwebui-extensions` repository.
Follow these comprehensive guidelines to ensure robust, reliable, and cost-effective testing.
## 1. Test Structure & Placement
- **Unit Tests**: Place in the `tests/` directory at the root of the repository. Name files `test_<module>.py`.
- **Integration/Debug Scripts**: Place in `plugins/debug/<plugin_name>/`. Name files `debug_<feature>.py` or `inspect_<feature>.py`.
- **Fixtures**: Use `conftest.py` for shared fixtures (e.g., mock users, mock emitters, mock database sessions).
## 2. Model Usage & Cost Control (CRITICAL)
When writing tests or debug scripts that actually invoke an LLM:
- **Allowed Models**: You MUST use low-cost models: `gpt-5-mini` (Preferred) or `gpt-4.1`.
- **Forbidden**: NEVER use expensive models (like `gpt-4-turbo`, `claude-3-opus`) in automated tests unless explicitly requested by the user.
- **API Keys**: Never hardcode API keys. Always read from environment variables (`os.getenv("OPENAI_API_KEY")`) or a `.env` file.
## 3. Mocking OpenWebUI Internals
OpenWebUI plugins rely heavily on injected runtime variables. Your tests must mock these accurately:
- **`__user__`**: Mock as a dictionary. Always test both with a full user object and an empty/None object to ensure fallback logic works.
```python
mock_user_en = {"id": "u1", "name": "Alice", "language": "en-US"}
mock_user_zh = {"id": "u2", "name": "Bob", "language": "zh-CN"}
mock_user_none = None
```
- **`__event_emitter__`**: Mock as an async callable that records emitted events for assertion.
```python
async def mock_emitter(event: dict):
emitted_events.append(event)
```
- **`__event_call__`**: Mock as an async callable. To test Antigravity timeout guards, you must occasionally mock this to sleep longer than the timeout (e.g., `await asyncio.sleep(3.0)`) to ensure `asyncio.wait_for` catches it.
## 4. Testing Async Code
- All OpenWebUI plugin entry points (`action`, `inlet`, `outlet`) are asynchronous.
- Use `@pytest.mark.asyncio` for all test functions.
- Ensure you `await` all plugin method calls.
## 5. i18n (Internationalization) Testing
Since all plugins must be single-file i18n:
- **Mandatory**: Write parameterized tests to verify output in both English (`en-US`) and Chinese (`zh-CN`).
- Verify that if an unsupported language is passed (e.g., `fr-FR`), the system correctly falls back to the default (usually `en-US`).
## 6. Antigravity & Safety Testing
- **Timeout Guards**: Explicitly test that frontend JS executions (`__event_call__`) do not hang the backend. Assert that a `TimeoutError` is caught and handled gracefully.
- **State Leakage**: For `Filter` plugins (which are singletons), write tests that simulate concurrent requests from different users to ensure no state leaks across `self`.
## 7. Assertions & Best Practices
- Assert on **behavior and output**, not internal implementation details.
- For HTML/Markdown generation plugins, use Regex or BeautifulSoup to assert the presence of required tags (e.g., `<!-- OPENWEBUI_PLUGIN_OUTPUT -->`) rather than exact string matching.
- Keep tests isolated. Do not rely on the execution order of tests.

71
.github/skills/README.md vendored Normal file
View File

@@ -0,0 +1,71 @@
# Agent Skills Index
This folder contains reusable Agent Skills for GitHub Copilot / VS Code custom agent workflows.
## Available Skills
- **community-announcer**
- Purpose: Generate community announcement content and related assets.
- Entry: `community-announcer/SKILL.md`
- **doc-mirror-sync**
- Purpose: Sync mirrored documentation content and helper scripts.
- Entry: `doc-mirror-sync/SKILL.md`
- **gh-issue-replier**
- Purpose: Draft standardized issue replies with templates.
- Entry: `gh-issue-replier/SKILL.md`
- **gh-issue-scheduler**
- Purpose: Schedule and discover unanswered issues for follow-up.
- Entry: `gh-issue-scheduler/SKILL.md`
- **i18n-validator**
- Purpose: Validate translation key consistency across i18n dictionaries.
- Entry: `i18n-validator/SKILL.md`
- **plugin-scaffolder**
- Purpose: Scaffold OpenWebUI plugin boilerplate with repository standards.
- Entry: `plugin-scaffolder/SKILL.md`
- **version-bumper**
- Purpose: Assist with semantic version bumping workflows.
- Entry: `version-bumper/SKILL.md`
- **xlsx-single-file**
- Purpose: Single-file spreadsheet operations workflow without LibreOffice.
- Entry: `xlsx-single-file/SKILL.md`
---
## Release Pipeline Skills
These four skills form a complete release pipeline and are designed to be used in sequence:
```
release-prep → pr-submitter → pr-reviewer → release-finalizer
(prepare) (push & PR) (respond to review) (merge & close issue)
```
- **release-prep**
- Purpose: Full release preparation — version sync across 7+ files, bilingual release notes creation, consistency check, and commit.
- Entry: `release-prep/SKILL.md`
- **pr-submitter**
- Purpose: Shell-escape-safe PR submission — writes body to temp file, validates sections, pushes branch, creates PR via `gh pr create --body-file`.
- Entry: `pr-submitter/SKILL.md`
- **pr-reviewer**
- Purpose: Fetch PR review comments, categorize feedback, implement fixes, commit and push, reply to reviewers.
- Entry: `pr-reviewer/SKILL.md`
- **release-finalizer**
- Purpose: Merge release PR to main with proper commit message, auto-link and close related issues, post closing messages.
- Entry: `release-finalizer/SKILL.md`
## Notes
- Skill definitions follow the expected location pattern:
- `.github/skills/<skill-name>/SKILL.md`
- Each skill may include optional `assets/`, `references/`, and `scripts/` folders.
- This directory mirrors `.gemini/skills` for compatibility.

View File

@@ -0,0 +1,23 @@
---
name: community-announcer
description: Drafts engaging English and Chinese update announcements for the OpenWebUI Community and other social platforms. Use when a new version is released.
---
# Community Announcer
## Overview
Automates the drafting of high-impact update announcements.
## Workflow
1. **Source Intel**: Read the latest version's `What's New` section from `README.md`.
2. **Drafting**: Create two versions:
- **Community Post**: Professional, structured, technical.
- **Catchy Short**: For Discord/Twitter, use emojis and bullet points.
3. **Multi-language**: Generate BOTH English and Chinese versions automatically.
## Announcement Structure (Recommended)
- **Headline**: "Update vX.X.X - [Main Feature]"
- **Introduction**: Brief context.
- **Key Highlights**: Bulleted list of fixes/features.
- **Action**: "Download from [Market Link]"
- **Closing**: Thanks and Star request.

14
.github/skills/doc-mirror-sync/SKILL.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: doc-mirror-sync
description: Automatically synchronizes plugin READMEs to the official documentation directory (docs/). Use after editing a plugin's local documentation to keep the MkDocs site up to date.
---
# Doc Mirror Sync
## Overview
Automates the mirroring of `plugins/{type}/{name}/README.md` to `docs/plugins/{type}/{name}.md`.
## Workflow
1. Identify changed READMEs.
2. Copy content to corresponding mirror paths.
3. Update version badges in `docs/plugins/{type}/index.md`.

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python3
import os
import shutil
import re
def sync_mirrors():
plugins_root = "plugins"
docs_root = "docs/plugins"
types = ["actions", "filters", "pipes", "pipelines", "tools"]
for t in types:
src_type_dir = os.path.join(plugins_root, t)
dest_type_dir = os.path.join(docs_root, t)
if not os.path.exists(src_type_dir): continue
os.makedirs(dest_type_dir, exist_ok=True)
for name in os.listdir(src_type_dir):
plugin_dir = os.path.join(src_type_dir, name)
if not os.path.isdir(plugin_dir): continue
# Sync README.md -> docs/plugins/{type}/{name}.md
src_readme = os.path.join(plugin_dir, "README.md")
if os.path.exists(src_readme):
dest_readme = os.path.join(dest_type_dir, f"{name}.md")
shutil.copy(src_readme, dest_readme)
print(f"✅ Mirrored: {t}/{name} (EN)")
# Sync README_CN.md -> docs/plugins/{type}/{name}.zh.md
src_readme_cn = os.path.join(plugin_dir, "README_CN.md")
if os.path.exists(src_readme_cn):
dest_readme_zh = os.path.join(dest_type_dir, f"{name}.zh.md")
shutil.copy(src_readme_cn, dest_readme_zh)
print(f"✅ Mirrored: {t}/{name} (ZH)")
if __name__ == "__main__":
sync_mirrors()

View File

@@ -0,0 +1,51 @@
---
name: gh-issue-replier
description: Professional English replier for GitHub issues. Use when a task is completed, a bug is fixed, or more info is needed from the user. Automates replying using the 'gh' CLI tool.
---
# Gh Issue Replier
## Overview
The `gh-issue-replier` skill enables Gemini CLI to interact with GitHub issues professionally. It enforces English for all communications and leverages the `gh` CLI to post comments.
## Workflow
1. **Identify the Issue**: Find the issue number (e.g., #49).
2. **Check Star Status**: Run the bundled script to check if the author has starred the repo.
* Command: `bash scripts/check_star.sh <issue-number>`
* Interpretation:
* Exit code **0**: User has starred. Use "Already Starred" templates.
* Exit code **1**: User has NOT starred. Include "Star Request" in the reply.
3. **Select a Template**: Load [templates.md](references/templates.md) to choose a suitable English response pattern.
4. **Draft the Reply**: Compose a concise message based on the star status.
5. **Post the Comment**: Use the `gh` tool to submit the reply.
## Tool Integration
### Check Star Status
```bash
bash scripts/check_star.sh <issue-number>
```
### Post Comment
```bash
gh issue comment <issue-number> --body "<message-body>"
```
Example (if user has NOT starred):
```bash
gh issue comment 49 --body "This has been fixed in v1.2.7. If you find this helpful, a star on the repo would be much appreciated! ⭐"
```
Example (if user HAS starred):
```bash
gh issue comment 49 --body "This has been fixed in v1.2.7. Thanks for your support!"
```
## Guidelines
- **Language**: ALWAYS use English for the comment body, even if the system prompt or user conversation is in another language.
- **Tone**: Professional, helpful, and appreciative.
- **Precision**: When announcing a fix, mention the specific version or the logic change (e.g., "Updated regex pattern").
- **Closing**: If the issue is resolved and you have permission, you can also use `gh issue close <number>`.

View File

@@ -0,0 +1,17 @@
# Reference Documentation for Gh Issue Replier
This is a placeholder for detailed reference documentation.
Replace with actual reference content or delete if not needed.
## Structure Suggestions
### API Reference Example
- Overview
- Authentication
- Endpoints with examples
- Error codes
### Workflow Guide Example
- Prerequisites
- Step-by-step instructions
- Best practices

View File

@@ -0,0 +1,45 @@
# Issue Reply Templates
Use these templates to craft professional English replies. Adjust placeholders like `@username`, `v1.2.x`, and `[commit hash]` as needed.
## 1. Acknowledging a New Issue
Use when you first see an issue and want to let the user know you are working on it.
- "Thank you for reporting this! I'm looking into it right now."
- "Thanks for bringing this to my attention. I'll try to reproduce this behavior and get back to you shortly."
## 2. Requesting More Information
Use when you need logs or specific details to fix the bug.
- "Could you please provide the **'Original'** vs **'Normalized'** content from your browser console logs (F12)? It would help a lot in debugging."
- "It would be very helpful if you could share the specific Markdown text that triggered this issue."
## 3. Announcing a Fix
Use when you have pushed the fix to the repository.
- "This has been fixed in version **v1.2.x**. You can update the plugin to resolve it."
- "I've just pushed a fix for this in [commit hash]. Please let me know if it works for you after updating."
- "The issue was caused by a greedy regex pattern. I've updated it to use a tempered greedy token to prevent incorrect merging."
## 4. Guiding to Official Market
Always provide the official market link to ensure the user gets the latest verified version.
- "The fix is now live! You can download the latest version from the official OpenWebUI Community page here: [Plugin Market Link]. Simply update the function in your OpenWebUI instance to apply the changes."
- "I recommend getting the updated version from the official store: [Link]. It includes the fix for the spacing issue we discussed."
## 5. Closing the Issue
Use when the issue is confirmed resolved.
- "Glad to hear it's working now! Closing this for now. Feel free to reopen it if the problem persists."
- "Since this is resolved, I'm closing this issue. Thanks again for your feedback!"
## 5. Pro-tip: Star Request
Gently handle star requests based on the user's current status.
### If User has NOT starred:
- "If you find this plugin helpful, a star on the repo would be much appreciated! ⭐"
- "We'd love your support! If this fixed your issue, please consider starring the repository. ⭐"
### If User HAS already starred:
- "Thanks again for starring the project and for your continuous support!"
- "I appreciate your support and for being a stargazer of this project!"

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Robust Star Checker v2
# Usage: ./check_star.sh <issue_number>
ISSUE_NUM=$1
if [ -z "$ISSUE_NUM" ]; then exit 2; fi
# 1. Get Repo and Author info
REPO_FULL=$(gh repo view --json owner,name -q ".owner.login + \"/\" + .name")
USER_LOGIN=$(gh issue view "$ISSUE_NUM" --json author -q ".author.login")
# 2. Use GraphQL for high precision (Detects stars even when REST 404s)
IS_STARRED=$(gh api graphql -f query='
query($owner:String!, $repo:String!, $user:String!) {
repository(owner:$owner, name:$repo) {
stargazers(query:$user, first:1) {
nodes {
login
}
}
}
}' -f owner="${REPO_FULL%/*}" -f repo="${REPO_FULL#*/}" -f user="$USER_LOGIN" -q ".data.repository.stargazers.nodes[0].login")
if [ "$IS_STARRED" == "$USER_LOGIN" ]; then
echo "Confirmed: @$USER_LOGIN HAS starred $REPO_FULL. ⭐"
exit 0
else
echo "Confirmed: @$USER_LOGIN has NOT starred $REPO_FULL."
exit 1
fi

View File

@@ -0,0 +1,42 @@
---
name: gh-issue-scheduler
description: Finds all open GitHub issues that haven't been replied to by the owner, summarizes them, and generates a solution plan. Use when the user wants to audit pending tasks or plan maintenance work.
---
# Gh Issue Scheduler
## Overview
The `gh-issue-scheduler` skill helps maintainers track community feedback by identifying unaddressed issues and drafting actionable technical plans to resolve them.
## Workflow
1. **Identify Unanswered Issues**: Run the bundled script to fetch issues without owner replies.
* Command: `bash scripts/find_unanswered.sh`
2. **Analyze and Summarize**: For each identified issue, summarize the core problem and the user's intent.
3. **Generate Solution Plans**: Draft a technical "Action Plan" for each issue, including:
* **Root Cause Analysis** (if possible)
* **Proposed Fix/Implementation**
* **Verification Strategy**
4. **Present to User**: Display a structured report of all pending issues and their respective plans.
## Tool Integration
### Find Unanswered Issues
```bash
bash scripts/find_unanswered.sh
```
## Report Format
When presenting the summary, use the following Markdown structure:
### 📋 Unanswered Issues Audit
#### Issue #[Number]: [Title]
- **Author**: @username
- **Summary**: Concise description of the problem.
- **Action Plan**:
1. Step 1 (e.g., Investigate file X)
2. Step 2 (e.g., Apply fix Y)
3. Verification (e.g., Run test Z)

View File

@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Fetch all open issues and filter for those without responses from the owner/collaborators.
# Uses 'gh' CLI.
REPO_FULL=$(gh repo view --json owner,name -q ".owner.login + "/" + .name")
OWNER=${REPO_FULL%/*}
# 1. Get all open issues
OPEN_ISSUES=$(gh issue list --state open --json number,title,author,createdAt --limit 100)
echo "Analysis for repository: $REPO_FULL"
echo "------------------------------------"
# Process each issue
echo "$OPEN_ISSUES" | jq -c '.[]' | while read -r issue; do
NUMBER=$(echo "$issue" | jq -r '.number')
TITLE=$(echo "$issue" | jq -r '.title')
AUTHOR=$(echo "$issue" | jq -r '.author.login')
# Check comments for owner responses
# We look for comments where the author is the repo owner
COMMENTS=$(gh issue view "$NUMBER" --json comments -q ".comments[].author.login" 2>/dev/null)
HAS_OWNER_REPLY=false
for COMMENT_AUTHOR in $COMMENTS; do
if [ "$COMMENT_AUTHOR" == "$OWNER" ]; then
HAS_OWNER_REPLY=true
break
fi
done
if [ "$HAS_OWNER_REPLY" == "false" ]; then
echo "ISSUE_START"
echo "ID: $NUMBER"
echo "Title: $TITLE"
echo "Author: $AUTHOR"
echo "Description:"
gh issue view "$NUMBER" --json body -q ".body"
echo "ISSUE_END"
fi
done

14
.github/skills/i18n-validator/SKILL.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: i18n-validator
description: Validates multi-language consistency in the TRANSLATIONS dictionary of a plugin. Use to check if any language keys are missing or if translations need updating.
---
# I18n Validator
## Overview
Ensures all 12 supported languages (en-US, zh-CN, etc.) have aligned translation keys.
## Features
- Detects missing keys in non-English dictionaries.
- Suggests translations using the core AI engine.
- Validates the `fallback_map` for variant redirects.

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import sys
import ast
import os
def check_i18n(file_path):
if not os.path.exists(file_path):
print(f"Error: File not found {file_path}")
return
with open(file_path, 'r', encoding='utf-8') as f:
tree = ast.parse(f.read())
translations = {}
for node in tree.body:
if isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Name) and target.id == "TRANSLATIONS":
translations = ast.literal_eval(node.value)
break
if not translations:
print("⚠️ No TRANSLATIONS dictionary found.")
return
# Base keys from English
base_lang = "en-US"
if base_lang not in translations:
print(f"❌ Error: {base_lang} missing in TRANSLATIONS.")
return
base_keys = set(translations[base_lang].keys())
print(f"🔍 Analyzing {file_path}...")
print(f"Standard keys ({len(base_keys)}): {', '.join(sorted(base_keys))}
")
for lang, keys in translations.items():
if lang == base_lang: continue
lang_keys = set(keys.keys())
missing = base_keys - lang_keys
extra = lang_keys - base_keys
if missing:
print(f"{lang}: Missing {len(missing)} keys: {', '.join(missing)}")
if extra:
print(f"⚠️ {lang}: Has {len(extra)} extra keys: {', '.join(extra)}")
if not missing and not extra:
print(f"{lang}: Aligned.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: validate_i18n.py <path_to_plugin.py>")
sys.exit(1)
check_i18n(sys.argv[1])

View File

@@ -0,0 +1,19 @@
---
name: plugin-scaffolder
description: Generates a standardized single-file i18n Python plugin template based on project standards. Use when starting a new plugin development to skip boilerplate writing.
---
# Plugin Scaffolder
## Overview
Generates compliant OpenWebUI plugin templates with built-in i18n, common utility methods, and required docstring fields.
## Usage
1. Provide the **Plugin Name** and **Type** (action/filter/pipe).
2. The skill will generate the `.py` file and the bilingual `README` files.
## Template Standard
- `Valves(BaseModel)` with `UPPER_SNAKE_CASE`
- `_get_user_context` with JS fallback and timeout
- `_emit_status` and `_emit_debug_log` methods
- Standardized docstring metadata

View File

@@ -0,0 +1,34 @@
# {{TITLE}}
**Author:** [Fu-Jie](https://github.com/Fu-Jie/openwebui-extensions) | **Version:** 0.1.0 | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT
{{DESCRIPTION}}
## 🔥 What's New in v0.1.0
* Initial release of {{TITLE}}.
## 🌐 Multilingual Support
Supports automatic interface and status switching for the following languages:
`English`, `简体中文`, `繁體中文 (香港)`, `繁體中文 (台灣)`, `한국어`, `日本語`, `Français`, `Deutsch`, `Español`, `Italiano`, `Tiếng Việt`, `Bahasa Indonesia`.
## ✨ Core Features
* Feature 1
* Feature 2
## How to Use 🛠️
1. Install the plugin in Open WebUI.
2. Configure settings in Valves.
## Configuration (Valves) ⚙️
| Parameter | Default | Description |
| :--- | :--- | :--- |
| `priority` | `50` | Execution priority. |
## ⭐ Support
If this plugin has been useful, a star on [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) is a big motivation for me. Thank you for the support.

View File

@@ -0,0 +1,80 @@
"""
title: {{TITLE}}
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
description: {{DESCRIPTION}}
"""
import asyncio
import logging
import json
from typing import Optional, Dict, Any, List, Callable, Awaitable
from pydantic import BaseModel, Field
from fastapi import Request
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
TRANSLATIONS = {
"en-US": {"status_starting": "Starting {{TITLE}}..."},
"zh-CN": {"status_starting": "正在启动 {{TITLE}}..."},
"zh-HK": {"status_starting": "正在啟動 {{TITLE}}..."},
"zh-TW": {"status_starting": "正在啟動 {{TITLE}}..."},
"ko-KR": {"status_starting": "{{TITLE}} 시작 중..."},
"ja-JP": {"status_starting": "{{TITLE}} を起動中..."},
"fr-FR": {"status_starting": "Démarrage de {{TITLE}}..."},
"de-DE": {"status_starting": "{{TITLE}} wird gestartet..."},
"es-ES": {"status_starting": "Iniciando {{TITLE}}..."},
"it-IT": {"status_starting": "Avvio di {{TITLE}}..."},
"vi-VN": {"status_starting": "Đang khởi động {{TITLE}}..."},
"id-ID": {"status_starting": "Memulai {{TITLE}}..."},
}
class {{CLASS_NAME}}:
class Valves(BaseModel):
priority: int = Field(default=50, description="Priority level (lower = earlier).")
show_status: bool = Field(default=True, description="Show status updates in UI.")
def __init__(self):
self.valves = self.Valves()
self.fallback_map = {
"zh": "zh-CN", "en": "en-US", "ko": "ko-KR", "ja": "ja-JP",
"fr": "fr-FR", "de": "de-DE", "es": "es-ES", "it": "it-IT",
"vi": "vi-VN", "id": "id-ID"
}
def _get_translation(self, lang: str, key: str, **kwargs) -> str:
target_lang = lang
if target_lang not in TRANSLATIONS:
base = target_lang.split("-")[0]
target_lang = self.fallback_map.get(base, "en-US")
lang_dict = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"])
text = lang_dict.get(key, TRANSLATIONS["en-US"].get(key, key))
return text.format(**kwargs) if kwargs else text
async def _get_user_context(self, __user__: Optional[dict], __event_call__: Optional[Callable] = None, __request__: Optional[Request] = None) -> dict:
user_data = __user__ if isinstance(__user__, dict) else {}
user_language = user_data.get("language", "en-US")
if __event_call__:
try:
js = "try { return (document.documentElement.lang || localStorage.getItem('locale') || navigator.language || 'en-US'); } catch (e) { return 'en-US'; }"
frontend_lang = await asyncio.wait_for(__event_call__({"type": "execute", "data": {"code": js}}), timeout=2.0)
if frontend_lang: user_language = frontend_lang
except: pass
return {"user_language": user_language}
async def {{METHOD_NAME}}(self, body: dict, __user__: Optional[dict] = None, __event_emitter__=None, __event_call__=None, __request__: Optional[Request] = None) -> dict:
if self.valves.show_status and __event_emitter__:
user_ctx = await self._get_user_context(__user__, __event_call__, __request__)
msg = self._get_translation(user_ctx["user_language"], "status_starting")
await __event_emitter__({"type": "status", "data": {"description": msg, "done": False}})
# Implement core logic here
if self.valves.show_status and __event_emitter__:
await __event_emitter__({"type": "status", "data": {"description": "Done", "done": True}})
return body

View File

@@ -0,0 +1,80 @@
"""
title: {{TITLE}}
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
description: {{DESCRIPTION}}
"""
import asyncio
import logging
import json
from typing import Optional, Dict, Any, List, Callable, Awaitable
from pydantic import BaseModel, Field
from fastapi import Request
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
TRANSLATIONS = {
"en-US": {"status_starting": "Starting {{TITLE}}..."},
"zh-CN": {"status_starting": "正在启动 {{TITLE}}..."},
"zh-HK": {"status_starting": "正在啟動 {{TITLE}}..."},
"zh-TW": {"status_starting": "正在啟動 {{TITLE}}..."},
"ko-KR": {"status_starting": "{{TITLE}} 시작 중..."},
"ja-JP": {"status_starting": "{{TITLE}} を起動中..."},
"fr-FR": {"status_starting": "Démarrage de {{TITLE}}..."},
"de-DE": {"status_starting": "{{TITLE}} wird gestartet..."},
"es-ES": {"status_starting": "Iniciando {{TITLE}}..."},
"it-IT": {"status_starting": "Avvio di {{TITLE}}..."},
"vi-VN": {"status_starting": "Đang khởi động {{TITLE}}..."},
"id-ID": {"status_starting": "Memulai {{TITLE}}..."},
}
class {{CLASS_NAME}}:
class Valves(BaseModel):
priority: int = Field(default=50, description="Priority level (lower = earlier).")
show_status: bool = Field(default=True, description="Show status updates in UI.")
def __init__(self):
self.valves = self.Valves()
self.fallback_map = {
"zh": "zh-CN", "en": "en-US", "ko": "ko-KR", "ja": "ja-JP",
"fr": "fr-FR", "de": "de-DE", "es": "es-ES", "it": "it-IT",
"vi": "vi-VN", "id": "id-ID"
}
def _get_translation(self, lang: str, key: str, **kwargs) -> str:
target_lang = lang
if target_lang not in TRANSLATIONS:
base = target_lang.split("-")[0]
target_lang = self.fallback_map.get(base, "en-US")
lang_dict = TRANSLATIONS.get(target_lang, TRANSLATIONS["en-US"])
text = lang_dict.get(key, TRANSLATIONS["en-US"].get(key, key))
return text.format(**kwargs) if kwargs else text
async def _get_user_context(self, __user__: Optional[dict], __event_call__: Optional[Callable] = None, __request__: Optional[Request] = None) -> dict:
user_data = __user__ if isinstance(__user__, dict) else {}
user_language = user_data.get("language", "en-US")
if __event_call__:
try:
js = "try { return (document.documentElement.lang || localStorage.getItem('locale') || navigator.language || 'en-US'); } catch (e) { return 'en-US'; }"
frontend_lang = await asyncio.wait_for(__event_call__({"type": "execute", "data": {"code": js}}), timeout=2.0)
if frontend_lang: user_language = frontend_lang
except: pass
return {"user_language": user_language}
async def {{METHOD_NAME}}(self, body: dict, __user__: Optional[dict] = None, __event_emitter__=None, __event_call__=None, __request__: Optional[Request] = None) -> dict:
if self.valves.show_status and __event_emitter__:
user_ctx = await self._get_user_context(__user__, __event_call__, __request__)
msg = self._get_translation(user_ctx["user_language"], "status_starting")
await __event_emitter__({"type": "status", "data": {"description": msg, "done": False}})
# Implement core logic here
if self.valves.show_status and __event_emitter__:
await __event_emitter__({"type": "status", "data": {"description": "Done", "done": True}})
return body

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env python3
import sys
import os
def scaffold(p_type, p_name, title, desc):
target_dir = f"plugins/{p_type}/{p_name}"
os.makedirs(target_dir, exist_ok=True)
class_name = (
"Action"
if p_type == "actions"
else (
"Filter"
if p_type == "filters"
else "Tools" if p_type == "tools" else "Pipe"
)
)
method_name = (
"action"
if p_type == "actions"
else (
"outlet"
if p_type == "filters"
else "execute" if p_type == "tools" else "pipe"
)
)
replacements = {
"{{TITLE}}": title,
"{{DESCRIPTION}}": desc,
"{{CLASS_NAME}}": class_name,
"{{METHOD_NAME}}": method_name,
}
# Files to generate
templates = [
("assets/template.py.j2", f"{p_name}.py"),
("assets/README_template.md", "README.md"),
("assets/README_template.md", "README_CN.md"),
]
# Path relative to skill root
skill_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
for t_path, t_name in templates:
template_file = os.path.join(skill_root, t_path)
if not os.path.exists(template_file):
print(f"⚠️ Warning: Template not found {template_file}")
continue
with open(template_file, "r") as f:
content = f.read()
for k, v in replacements.items():
content = content.replace(k, v)
with open(os.path.join(target_dir, t_name), "w") as f:
f.write(content)
print(f"✅ Generated: {target_dir}/{t_name}")
if __name__ == "__main__":
if len(sys.argv) < 5:
print("Usage: scaffold.py <type> <name> <title> <desc>")
sys.exit(1)
scaffold(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

180
.github/skills/pr-reviewer/SKILL.md vendored Normal file
View File

@@ -0,0 +1,180 @@
---
name: pr-reviewer
description: Fetches PR review comments, analyzes requested changes, implements fixes, commits and pushes the resolution. Use after a reviewer has left comments on an open PR to close the feedback loop efficiently.
---
# PR Reviewer
## Overview
This skill automates the response cycle for code review. When a reviewer leaves comments on a Pull Request, this skill fetches all pending feedback, categorizes issues by severity, implements fixes, and submits a follow-up commit with appropriate review response comments.
## Prerequisites
- An open PR exists with pending review comments
- The local branch matches the PR's head branch
- `gh` CLI is authenticated
---
## Workflow
### Step 1 — Fetch Review State
Retrieve all review comments and overall review status:
```bash
# Get overall review decisions
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json reviews,reviewDecision,headRefName \
--jq '{decision: .reviewDecision, reviews: [.reviews[] | {author: .author.login, state: .state, body: .body}]}'
# Get inline code comments (specific line comments)
PAGER=cat GH_PAGER=cat gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/comments \
--jq '[.[] | {path: .path, line: .line, body: .body, author: .user.login, id: .id}]'
# Get general issue comments
PAGER=cat GH_PAGER=cat gh issue view <PR-NUMBER> --comments --json comments \
--jq '[.comments[] | {author: .author.login, body: .body}]'
```
Confirm the current local branch matches the PR head:
```bash
git branch --show-current
```
If mismatched, checkout the correct branch first.
### Step 2 — Categorize Review Feedback
Group feedback into categories:
| Category | Examples | Action |
|----------|---------|--------|
| **Code Bug** | Logic error, incorrect variable, broken condition | Fix code immediately |
| **Style / Formatting** | Indentation, naming convention, missing blank line | Fix code |
| **Documentation** | Missing i18n key, wrong version in README, typo | Fix docs |
| **Design Question** | Suggestion to restructure, alternative approach | Discuss with user before implementing |
| **Nitpick / Optional** | Minor style preferences reviewer marked as optional | Fix if quick; document if skipped |
| **Blocking** | Reviewer explicitly blocks merge | Must fix before proceeding |
Present the full categorized list to the user and confirm the resolution plan.
### Step 3 — Implement Fixes
For each accepted fix:
1. Read the affected file at the commented line for context:
```bash
sed -n '<line-5>,<line+10>p' <file-path>
```
2. Apply the fix using appropriate file edit tools
3. After editing, verify the specific area looks correct
**For code changes that might affect behavior:**
- Check if tests exist: `ls tests/test_*.py`
- If tests exist, run them: `python -m pytest tests/ -v`
**For documentation fixes:**
- If modifying README.md, check if `docs/` mirror needs the same fix
- Apply the same fix to both locations
### Step 4 — Run Consistency Checks
After all fixes are applied:
```bash
# Version consistency (if any version files were touched)
python3 scripts/check_version_consistency.py
# Quick syntax check for Python files
python3 -m py_compile plugins/{type}/{name}/{name}.py && echo "✅ Syntax OK"
```
### Step 5 — Stage and Commit
Create a new commit (do NOT amend if the branch has already been pushed, to avoid force-push):
```bash
git add -A
git status
```
Draft a Conventional Commits message for the fixup:
Format: `fix(scope): address review feedback`
Body should list what was fixed, referencing reviewer concerns:
```
fix(github-copilot-sdk): address review feedback from @reviewer
- Fix X per review comment on line Y of file Z
- Update README to clarify auth requirement
- Correct edge case in _parse_mcp_servers logic
```
```bash
git commit -m "<fixup commit message>"
```
### Step 6 — Push the Fix Commit
```bash
git push origin $(git branch --show-current)
```
**Force-push policy:**
- Use `git push` (non-force) by default
- Only use `git push --force-with-lease` if:
1. The user explicitly requests it, AND
2. The only change is an amended commit squash (cosmetic, no logic change)
3. Never use `--force` (without `--lease`)
### Step 7 — Respond to Reviewers
For each addressed review comment, post a reply:
```bash
# Reply to inline comment
gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/comments/<COMMENT-ID>/replies \
-X POST -f body="Fixed in commit <SHORT-SHA>. <Brief explanation of what was changed.>"
# General comment to summarize all fixes
gh issue comment <PR-NUMBER> --body "All review feedback addressed in commit <SHORT-SHA>:
- Fixed: <item 1>
- Fixed: <item 2>
Ready for re-review. 🙏"
```
### Step 8 — Re-Request Review (Optional)
If the reviewer had submitted a `CHANGES_REQUESTED` review, request a new review after fixes:
```bash
PAGER=cat GH_PAGER=cat gh api repos/Fu-Jie/openwebui-extensions/pulls/<PR-NUMBER>/requested_reviewers \
-X POST -f reviewers[]='<reviewer-login>'
```
---
## Decision Guide
### When NOT to implement a suggestion immediately
- **Design questions**: "Should this be a separate class?" — Present to user for decision
- **Optional nitpicks**: Reviewer marked as `nit:` — Ask user if they want to include it
- **Large refactors**: If fix would require changing >50 lines, propose a separate follow-up issue instead
### When to ask the user before proceeding
- Any fix involving behavioral changes to plugin logic
- Renaming Valve keys (breaking change — requires migration notes)
- Changes that affect the bilingual release notes already committed
---
## Anti-Patterns to Avoid
- ❌ Do NOT `git commit --amend` on a pushed commit without user approval for force-push
- ❌ Do NOT silently skip a reviewer's comment; always acknowledge it (implement or explain why not)
- ❌ Do NOT use `--force` (only `--force-with-lease` when absolutely necessary)
- ❌ Do NOT make unrelated changes in the fixup commit; keep scope focused on review feedback
- ❌ Do NOT respond to reviewer comments in Chinese if the PR language context is English

194
.github/skills/pr-submitter/SKILL.md vendored Normal file
View File

@@ -0,0 +1,194 @@
---
name: pr-submitter
description: Submits a feature branch as a Pull Request with a validated, properly formatted bilingual PR body. Handles shell-escape-safe body writing via temp files. Use after release-prep has committed all changes.
---
# PR Submitter
## Overview
This skill handles the final step of pushing a feature branch and creating a validated Pull Request on GitHub. Its primary purpose is to avoid the shell-escaping pitfalls (backticks, special characters in `gh pr create --body`) by always writing the PR body to a **temp file** first.
## Prerequisites
- All changes are committed (use `release-prep` skill first)
- The `gh` CLI is authenticated (`gh auth status`)
- Current branch is NOT `main` or `master`
---
## Workflow
### Step 0 — Initialize Temp Directory (Project-Based)
For all temporary files, use the project's `.temp/` directory instead of system `/tmp`:
```bash
# Create temp directory if it doesn't exist
mkdir -p .temp
```
**Why**: All temporary files stay within the project workspace, avoiding system `/tmp` pollution and better aligning with OpenWebUI workspace isolation principles.
### Step 1 — Pre-Flight Checks
Run these checks before any push:
```bash
# 1. Confirm not on protected branch
git branch --show-current
# 2. Verify there are commits to push
git log origin/$(git branch --show-current)..HEAD --oneline 2>/dev/null || echo "No remote tracking branch yet"
# 3. Check gh CLI auth
gh auth status
```
If any check fails, stop and report clearly.
### Step 2 — Collect PR Metadata
Gather:
- **PR Title**: Must follow Conventional Commits format, English only (e.g., `feat(github-copilot-sdk): release v0.8.0 with conditional tool filtering`)
- **Target base branch**: Default is `main`
- **Plugin name + version** (to build body sections)
- **Key changes** (reuse from release-prep or the latest What's New section)
### Step 3 — Build PR Body File (Shell-Escape-Safe)
**Always write the body to a temp file in `.temp/` directory.** Never embed multi-line markdown with special characters directly in a shell command.
```bash
cat > .temp/pr_body.md << 'HEREDOC'
## Summary
Brief one-sentence description of what this PR accomplishes.
## Changes
### New Features
- Feature 1 description
- Feature 2 description
### Bug Fixes
- Fix 1 description
## Plugin Version
- `PluginName` bumped to `vX.X.X`
## Documentation
- README.md / README_CN.md updated
- docs/ mirrors synced
## Testing
- [ ] Tested locally in OpenWebUI
- [ ] i18n validated (all language keys present)
- [ ] Version consistency check passed (`python3 scripts/check_version_consistency.py`)
---
## 变更摘要(中文)
简要描述本次 PR 的改动内容。
### 新功能
- 功能1描述
- 功能2描述
### 问题修复
- 修复1描述
HEREDOC
```
**Critical rules for the body file:**
- Use `<< 'HEREDOC'` (quoted heredoc) to prevent variable expansion
- Keep all backticks literal — they are safe inside a heredoc
- Paths like `/api/v1/files/` are safe too since heredoc doesn't interpret them as commands
### Step 4 — Validate PR Body
Before submitting, verify the body file contains expected sections:
```bash
# Check key sections exist
grep -q "## Summary" .temp/pr_body.md && echo "✅ Summary" || echo "❌ Summary missing"
grep -q "## Changes" .temp/pr_body.md && echo "✅ Changes" || echo "❌ Changes missing"
grep -q "## 变更摘要" .temp/pr_body.md && echo "✅ CN Section" || echo "❌ CN Section missing"
# Preview the body
cat .temp/pr_body.md
```
Ask the user to confirm the body content before proceeding.
### Step 5 — Push Branch
```bash
git push -u origin $(git branch --show-current)
```
If push is rejected (non-fast-forward), report to user and ask whether to force-push. **Do NOT force-push without explicit confirmation.**
### Step 6 — Create Pull Request
```bash
gh pr create \
--base main \
--head $(git branch --show-current) \
--title "<PR title from Step 2>" \
--body-file .temp/pr_body.md
```
Always use `--body-file`, never `--body` with inline markdown.
### Step 7 — Verify PR Creation
```bash
PAGER=cat GH_PAGER=cat gh pr view --json number,url,title,body --jq '{number: .number, url: .url, title: .title, body_preview: .body[:200]}'
```
Confirm:
- PR number and URL
- Title matches intended Conventional Commits format
- Body preview includes key sections (not truncated/corrupted)
If the body appears corrupted (empty sections, missing backtick content), use edit:
```bash
gh pr edit <PR-NUMBER> --body-file /tmp/pr_body.md
```
### Step 8 — Cleanup
```bash
rm -f .temp/pr_body.md
```
**Note**: The `.temp/` directory itself is preserved for reuse; only the individual PR body file is deleted. To fully clean up: `rm -rf .temp/`
Report final PR URL to the user.
---
## Shell-Escape Safety Rules
| Risk | Safe Approach |
|------|--------------|
| Backticks in `--body` | Write to file, use `--body-file` |
| Paths like `/api/...` | Safe in heredoc; risky in inline `--body` |
| Newlines in `--body` | File-based only |
| `$variable` expansion | Use `<< 'HEREDOC'` (quoted) |
| Double quotes in body | Safe in heredoc file |
| Temp file storage | Use `.temp/` dir, not `/tmp` |
| Cleanup after use | Always delete temp file (keep dir) |
---
## Anti-Patterns to Avoid
- ❌ Never use `--body "..."` with multi-line content directly in shell command
- ❌ Never interpolate variables directly into heredoc without quoting the delimiter
- ❌ Never force-push (`--force`) without explicit user confirmation
- ❌ Never target `main` as the source branch (only as base)
- ❌ Never skip the body validation step — a PR with empty body is worse than a delayed PR

View File

@@ -0,0 +1,208 @@
---
name: release-finalizer
description: Merges a release PR, associates it with resolved issues, replies to issue reporters, and closes issues. Use after PR review is complete and ready for merge. Closes the release cycle.
---
# Release Finalizer
## Overview
This skill completes the final step of the release cycle: merging the release PR to `main`, replying to all related issues with solutions, and automatically closing them using GitHub's issue linking mechanism.
## Prerequisites
- The PR is in `OPEN` state and ready to merge
- All status checks have passed (CI green)
- All review feedback has been addressed
- The PR relates to one or more GitHub issues (either in PR description or through commits)
---
## Workflow
### Step 1 — Pre-Merge Verification
Verify that the PR is ready:
```bash
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json state,statusCheckRollup,reviewDecision
```
Checklist:
-`state` is `OPEN`
-`statusCheckRollup` all have `conclusion: SUCCESS`
-`reviewDecision` is `APPROVED` or empty (no blocking reviews)
If any check fails, **do NOT merge**. Report the issue to the user.
### Step 2 — Identify Related Issues
Issues can be linked to a PR in multiple ways. Check the PR description and commit messages for keywords:
```bash
PAGER=cat GH_PAGER=cat gh pr view <PR-NUMBER> --json body,commits
```
Look for patterns like:
- `Closes #XX`, `Fixes #XX`, `Resolves #XX` (in description or commit bodies)
- `#XX` mentioned as "related to" or "addresses"
**Manual input**: If issue links are not in the PR, ask the user which issue(s) this PR resolves.
Extract all issue numbers into a list: `[#48, #52, ...]`
### Step 3 — Select Merge Strategy
Offer the user three options:
| Strategy | Git Behavior | Use Case |
|----------|-------------|----------|
| **Squash** | All commits squashed into one commit on main | Clean history, recommended for release PRs |
| **Rebase** | Linear history, no merge commit | Preserve commit granularity |
| **Merge** | Merge commit created | Preserve full PR context |
**Recommendation for release PRs**: Use `--squash` to create a single clean commit.
If user doesn't specify, default to `--squash`.
### Step 4 — Prepare Merge Commit Message
If using `--squash`, craft a single comprehensive commit message:
**Format** (Conventional Commits + Github linking):
```
type(scope): description
- Bullet point 1
- Bullet point 2
Closes #48
Closes #52
```
The `Closes #XX` keyword tells GitHub to automatically close those issues when the commit lands on `main`.
Example:
```
feat(pipes,filters): release Copilot SDK Pipe v0.8.0 and Files Filter v0.1.3
- Implement P1~P4 conditional tool filtering system
- Fix file publishing reliability across all storage backends
- Add strict file URL validation
- Update bilingual documentation
Closes #48
```
### Step 5 — Execute Merge
```bash
gh pr merge <PR-NUMBER> \
--squash \
--delete-branch \
-m "type(scope): description" \
-b "- Bullet 1\n- Bullet 2\n\nCloses #48"
```
**Key flags:**
- `--squash`: Squash commits (recommended for releases)
- `--delete-branch`: Delete the feature branch after merge
- `-m`: Commit subject
- `-b`: Commit body (supports `\n` for newlines)
Confirm the merge is successful; GitHub will automatically close related issues with `Closes #XX` keyword.
### Step 6 — Verify Auto-Close
GitHub automatically closes issues when a commit with `Closes #XX` lands on the default branch (`main`).
To verify:
```bash
PAGER=cat GH_PAGER=cat gh issue view <ISSUE-NUMBER> --json state
```
Should show `state: CLOSED`.
### Step 7 — Post Closing Message (Optional but Recommended)
For better UX, manually post a summary comment to **each issue** before it auto-closes (since auto-close happens silently):
```bash
gh issue comment <ISSUE-NUMBER> --body "
This has been fixed in PR #<PR-NUMBER>, which is now merged to main.
**Solution Summary:**
- <Key fix 1>
- <Key fix 2>
The fix will be available in the next plugin release. Thank you for reporting! ⭐
"
```
### Step 8 — (Optional) Regenerate Release Notes
If the merge revealed any final tweaks to release notes:
```bash
# Re-export release notes from merged commit
git log --oneline -1 <merged-commit-sha>
```
If needed, create a follow-up PR with doc polish (do NOT force-push the merged commit).
---
## Merge Strategy Decision Tree
```
Is this a patch/hotfix release?
├─ YES → Use --squash
└─ NO → Multi-feature release?
├─ YES → Use --squash (cleaner history)
└─ NO → Preserve detail?
├─ YES → Use --rebase
└─ NO → Use --merge (preserve PR context)
```
---
## Issue Auto-Close Keywords
These keywords in commit/PR messages will auto-close issues when merged to `main`:
- `Closes #XX`
- `Fixes #XX`
- `Resolves #XX`
- `close #XX` (case-insensitive)
- `fix #XX`
- `resolve #XX`
**Important**: The keyword must be on the **final commit that lands on** `main`. For squash merges, it must be in the squash commit message body.
---
## Anti-Patterns to Avoid
- ❌ Do NOT merge if any status checks are PENDING or FAILED
- ❌ Do NOT merge if there are blocking reviews (reviewDecision: `CHANGES_REQUESTED`)
- ❌ Do NOT merge without verifying the Conventional Commits format in the merge message
- ❌ Do NOT merge without including `Closes #XX` keywords for all related issues
- ❌ Do NOT assume issues will auto-close silently — post a courtesy comment first
- ❌ Do NOT delete the branch if it might be needed for cherry-pick or hotfixes later
---
## Troubleshooting
### Issue did not auto-close after merge
- Verify the `Closes #XX` keyword is in the **final commit message** (use `git log` to check)
- Ensure the commit is on the `main` branch
- GitHub sometimes takes a few seconds to process; refresh the issue page
### Multiple issues to close
- List all in separate `Closes #XX` lines in the commit body
- Each one will be independently auto-closed
### Want to close issue without merge?
- Use `gh issue close <ISSUE-NUMBER>` manually
- Only recommended if the PR was manually reverted or deemed invalid

144
.github/skills/release-prep/SKILL.md vendored Normal file
View File

@@ -0,0 +1,144 @@
---
name: release-prep
description: Orchestrates the full release preparation flow for a plugin — version sync across 7+ files, bilingual release notes creation, and commit message drafting. Use before submitting a PR. Does NOT push or create a PR; that is handled by pr-submitter.
---
# Release Prep
## Overview
This skill drives the complete pre-PR release pipeline. It enforces the repository rule that every release must synchronize the version number and changelog across **at least 7 locations** before a commit is created.
## Scope
This skill covers:
1. Version sync (delegates detail to `version-bumper` if needed)
2. Bilingual release notes file creation
3. 7-location consistency verification
4. Conventional Commits message drafting
5. `git add -A && git commit` execution
It **stops before** `git push` or `gh pr create`. Use the `pr-submitter` skill for those steps.
### Temporary File Convention
Any temporary files created during release prep (e.g., draft changelogs) must:
- Be written to the project's `.temp/` directory, **NOT** system `/tmp`
- Be cleaned up before commit using `rm -f .temp/file_name`
- Never be committed to git (add `.temp/` to `.gitignore`)
---
## Workflow
### Step 1 — Collect Release Info
Ask the user (or infer from current state) the following:
- **Plugin name** and **type** (actions / filters / pipes / tools)
- **New version number** (e.g., `0.8.0`)
- **Key changes** in English and Chinese (1-5 bullet points each)
If a `What's New` section already exists in README.md, extract it as the source of truth.
### Step 2 — Sync Version Across 7 Locations
Verify AND update the version string in all of the following. Mark each as ✅ or ❌:
| # | File | Location |
|---|------|----------|
| 1 | `plugins/{type}/{name}/{name}.py` | `version:` in docstring |
| 2 | `plugins/{type}/{name}/README.md` | `**Version:** x.x.x` metadata line |
| 3 | `plugins/{type}/{name}/README_CN.md` | `**Version:** x.x.x` metadata line |
| 4 | `docs/plugins/{type}/{name}.md` | `**Version:** x.x.x` metadata line |
| 5 | `docs/plugins/{type}/{name}.zh.md` | `**Version:** x.x.x` metadata line |
| 6 | `docs/plugins/{type}/index.md` | version badge for this plugin |
| 7 | `docs/plugins/{type}/index.zh.md` | version badge for this plugin |
Additionally update the root-level **updated date badge** in:
- `README.md``![updated](https://img.shields.io/badge/YYYY--MM--DD-gray?style=flat)`
- `README_CN.md` — same badge format
Use today's date (`YYYY-MM-DD`) for the badge.
### Step 3 — Update What's New (All 4 Doc Files)
The `What's New` / `最新更新` section must contain **only the most recent release's changes**. Previous entries should be removed from this section (they live in CHANGELOG or release notes files).
Update these 4 files' `What's New` / `最新更新` block consistently:
- `plugins/{type}/{name}/README.md`
- `plugins/{type}/{name}/README_CN.md`
- `docs/plugins/{type}/{name}.md`
- `docs/plugins/{type}/{name}.zh.md`
### Step 4 — Create Bilingual Release Notes Files
Create two versioned release notes files:
**Path**: `plugins/{type}/{name}/v{version}.md`
**Path**: `plugins/{type}/{name}/v{version}_CN.md`
#### Required Sections
Each file must include:
1. **Title**: `# v{version} Release Notes` (EN) / `# v{version} 版本发布说明` (CN)
2. **Overview**: One paragraph summarizing this release
3. **New Features** / **新功能**: Bulleted list of features
4. **Bug Fixes** / **问题修复**: Bulleted list of fixes
5. **Migration Notes** / **迁移说明**: Breaking changes or Valve key renames (omit section if none)
6. **Companion Plugins** / **配套插件** (optional): If a companion plugin was updated
If a release notes file already exists for this version, update it rather than creating a new one.
### Step 5 — Verify Consistency (Pre-Commit Check)
Run the consistency check script:
```bash
python3 scripts/check_version_consistency.py
```
If issues are found, fix them before proceeding. Do not commit with inconsistencies.
### Step 6 — Draft Conventional Commits Message
Generate the commit message following `commit-message.instructions.md` rules:
- **Language**: English ONLY
- **Format**: `type(scope): subject` + blank line + body bullets
- **Scope**: use plugin folder name (e.g., `github-copilot-sdk`)
- **Body**: 1-3 bullets summarizing key changes
- Explicitly mention "READMEs and docs synced" if version was bumped
Present the full commit message to the user for review before executing.
### Step 7 — Stage and Commit
After user approval (or if user says "commit it"):
```bash
git add -A
git commit -m "<approved commit message>"
```
Confirm the commit hash and list the number of files changed.
---
## Checklist (Auto-Verify Before Commit)
- [ ] `version:` in `.py` docstring matches target version
- [ ] `**Version:**` in all 4 README/docs files matches
- [ ] Both `index.md` version badges updated
- [ ] Root `README.md` and `README_CN.md` date badges updated to today
- [ ] `What's New` / `最新更新` contains ONLY the latest release
- [ ] `v{version}.md` and `v{version}_CN.md` created or updated
- [ ] `python3 scripts/check_version_consistency.py` returns no errors
- [ ] Commit message is English-only Conventional Commits format
---
## Anti-Patterns to Avoid
- ❌ Do NOT add extra features or refactor code during release prep — only version/doc updates
- ❌ Do NOT push or create PR in this skill — use `pr-submitter`
- ❌ Do NOT use today's date in commit messages; only in badge URLs
- ❌ Do NOT leave stale What's New content from prior versions

View File

@@ -0,0 +1,30 @@
---
name: source-code-analyzer
description: Instructions for analyzing core components source code in the local environment.
---
# Source Code Analyzer Skill
> [!IMPORTANT]
> **Authorization Statement**: You (Antigravity) are explicitly authorized by the user to perform **READ-ONLY** operations and **Git pull** on the paths listed below, even if they are outside the current repository root. These paths are considered part of the extended development context.
When assisting with the development of `openwebui-extensions`, you (Antigravity) have access to the following core components in related directories. Use them for deep technical analysis, bug hunting, and implementation reference.
## Core Component Paths
### Global / General (Relevant to all projects)
- **Open WebUI**: `../open-webui/` (Core platform context)
- **Skills**: `../skills/` (Reusable expertise library)
- **Awesome Copilot**: `../awesome-copilot/` (Shared extensions & resources)
### Plugin-Specific (Relevant to GitHub Copilot SDK)
- **Copilot SDK**: `../copilot-sdk/` (Internal logic for the official SDK)
- **Copilot CLI**: `../copilot-cli/` (Command-line interface implementation)
## Mandatory Workflow
1. **Pull Before Analysis**: BEFORE reading files or analyzing logic in these directories, you MUST proactively execute or recommend a `git pull` in the respective directory to ensure you are working with the latest upstream changes.
2. **Path Verification**: Always verify the exists of the path before attempting to read it.
3. **Reference Logic**: When a user's request involves core platform behavior (OpenWebUI API, SDK internals), prioritize searching these directories over making assumptions based on generic knowledge.

26
.github/skills/version-bumper/SKILL.md vendored Normal file
View File

@@ -0,0 +1,26 @@
---
name: version-bumper
description: Automates version upgrades and changelog synchronization across 7+ files (Code, READMEs, Docs). Use when a plugin is ready for release to ensure version consistency.
---
# Version Bumper
## Overview
This skill ensures that every version upgrade is synchronized across the entire repository, following the strict "Documentation Sync" rule in GEMINI.md.
## Workflow
1. **Prepare Info**: Gather the new version number and brief changelogs in both English and Chinese.
2. **Auto-Patch**: The skill will help you identify and update:
- `plugins/.../name.py` (docstring version)
- `plugins/.../README.md` (metadata & What's New)
- `plugins/.../README_CN.md` (metadata & 最新更新)
- `docs/plugins/...md` (mirrors)
- `docs/plugins/index.md` (version badge)
- `README.md` (updated date badge)
3. **Verify**: Check the diffs to ensure no formatting was broken.
## Tool Integration
Execute the bump script (draft):
```bash
python3 scripts/bump.py <version> "<message_en>" "<message_zh>"
```

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import sys
import os
import re
from datetime import datetime
def patch_file(file_path, old_pattern, new_content, is_regex=False):
if not os.path.exists(file_path):
print(f"Warning: File not found: {file_path}")
return False
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if is_regex:
new_content_result = re.sub(old_pattern, new_content, content, flags=re.MULTILINE)
else:
new_content_result = content.replace(old_pattern, new_content)
if new_content_result != content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(new_content_result)
print(f"✅ Patched: {file_path}")
return True
else:
print(f" No change needed: {file_path}")
return False
def bump_version(plugin_type, plugin_name, new_version, msg_en, msg_zh):
print(f"🚀 Bumping {plugin_name} ({plugin_type}) to {new_version}...")
today = datetime.now().strftime("%Y-%m-%d")
today_badge = today.replace("-", "--")
# 1. Patch Plugin Python File
py_file = f"plugins/{plugin_type}/{plugin_name}/{plugin_name}.py"
patch_file(py_file, r"version: \d+\.\d+\.\d+", f"version: {new_version}", is_regex=True)
# 2. Patch Plugin READMEs
readme_en = f"plugins/{plugin_type}/{plugin_name}/README.md"
readme_zh = f"plugins/{plugin_type}/{plugin_name}/README_CN.md"
# Update version in metadata
patch_file(readme_en, r"\*\*Version:\*\* \d+\.\d+\.\d+", f"**Version:** {new_version}", is_regex=True)
patch_file(readme_zh, r"\*\*版本:\*\* \d+\.\d+\.\d+", f"**版本:** {new_version}", is_regex=True)
# Update What's New (Assuming standard headers)
patch_file(readme_en, r"## 🔥 What's New in v.*?\n", f"## 🔥 What's New in v{new_version}\n\n* {msg_en}\n", is_regex=True)
patch_file(readme_zh, r"## 🔥 最新更新 v.*?\n", f"## 🔥 最新更新 v{new_version}\n\n* {msg_zh}\n", is_regex=True)
# 3. Patch Docs Mirrors
doc_en = f"docs/plugins/{plugin_type}/{plugin_name}.md"
doc_zh = f"docs/plugins/{plugin_type}/{plugin_name}.zh.md"
patch_file(doc_en, r"\*\*Version:\*\* \d+\.\d+\.\d+", f"**Version:** {new_version}", is_regex=True)
patch_file(doc_zh, r"\*\*版本:\*\* \d+\.\d+\.\d+", f"**版本:** {new_version}", is_regex=True)
# 4. Patch Root READMEs (Updated Date Badge)
patch_file("README.md", r"badge/202\d--\d\d--\d\d-gray", f"badge/{today_badge}-gray", is_regex=True)
patch_file("README_CN.md", r"badge/202\d--\d\d--\d\d-gray", f"badge/{today_badge}-gray", is_regex=True)
print("\n✨ All synchronization tasks completed.")
return True
if __name__ == "__main__":
if len(sys.argv) < 6:
print("Usage: bump.py <type> <name> <version> <msg_en> <msg_zh>")
print("Example: bump.py filters markdown_normalizer 1.2.8 'Fix bug' '修复错误'")
sys.exit(1)
bump_version(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])

View File

@@ -8,10 +8,8 @@
name: Community Stats
on:
# 每小时整点运行
schedule:
- cron: '0 * * * *'
# 手动触发
workflow_dispatch:
permissions:
@@ -41,21 +39,16 @@ jobs:
run: |
if [ -f docs/community-stats.json ]; then
echo "total_posts=$(jq -r '.total_posts // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "total_points=$(jq -r '.user.total_points // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "followers=$(jq -r '.user.followers // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
# 提取所有插件的版本号,生成一个排序后的字符串用于比较
echo "versions=$(jq -r '[.posts[].version] | sort | join(",")' docs/community-stats.json)" >> $GITHUB_OUTPUT
else
echo "total_posts=0" >> $GITHUB_OUTPUT
echo "total_points=0" >> $GITHUB_OUTPUT
echo "followers=0" >> $GITHUB_OUTPUT
echo "versions=" >> $GITHUB_OUTPUT
fi
- name: Generate stats report
env:
OPENWEBUI_API_KEY: ${{ secrets.OPENWEBUI_API_KEY }}
OPENWEBUI_USER_ID: ${{ secrets.OPENWEBUI_USER_ID }}
GIST_TOKEN: ${{ secrets.GIST_TOKEN }}
GIST_ID: ${{ secrets.GIST_ID }}
run: |
python scripts/openwebui_stats.py
@@ -63,53 +56,22 @@ jobs:
id: new_stats
run: |
echo "total_posts=$(jq -r '.total_posts // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "total_points=$(jq -r '.user.total_points // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "followers=$(jq -r '.user.followers // 0' docs/community-stats.json)" >> $GITHUB_OUTPUT
echo "versions=$(jq -r '[.posts[].version] | sort | join(",")' docs/community-stats.json)" >> $GITHUB_OUTPUT
- name: Check for significant changes
id: check_changes
run: |
OLD_POSTS="${{ steps.old_stats.outputs.total_posts }}"
NEW_POSTS="${{ steps.new_stats.outputs.total_posts }}"
OLD_POINTS="${{ steps.old_stats.outputs.total_points }}"
NEW_POINTS="${{ steps.new_stats.outputs.total_points }}"
OLD_FOLLOWERS="${{ steps.old_stats.outputs.followers }}"
NEW_FOLLOWERS="${{ steps.new_stats.outputs.followers }}"
OLD_VERSIONS="${{ steps.old_stats.outputs.versions }}"
NEW_VERSIONS="${{ steps.new_stats.outputs.versions }}"
SHOULD_COMMIT="false"
CHANGE_REASON=""
# 检查新增插件
if [ "$NEW_POSTS" -gt "$OLD_POSTS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="new plugin added ($OLD_POSTS -> $NEW_POSTS)"
echo "📦 New plugin detected: $OLD_POSTS -> $NEW_POSTS"
fi
# 检查版本变更
if [ "$OLD_VERSIONS" != "$NEW_VERSIONS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="${CHANGE_REASON:+$CHANGE_REASON, }plugin version updated"
echo "🔄 Plugin version changed"
fi
# 检查积分增加
if [ "$NEW_POINTS" -gt "$OLD_POINTS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="${CHANGE_REASON:+$CHANGE_REASON, }points increased ($OLD_POINTS -> $NEW_POINTS)"
echo "⭐ Points increased: $OLD_POINTS -> $NEW_POINTS"
fi
# 检查粉丝增加
if [ "$NEW_FOLLOWERS" -gt "$OLD_FOLLOWERS" ]; then
SHOULD_COMMIT="true"
CHANGE_REASON="${CHANGE_REASON:+$CHANGE_REASON, }followers increased ($OLD_FOLLOWERS -> $NEW_FOLLOWERS)"
echo "👥 Followers increased: $OLD_FOLLOWERS -> $NEW_FOLLOWERS"
fi
echo "should_commit=$SHOULD_COMMIT" >> $GITHUB_OUTPUT
echo "change_reason=$CHANGE_REASON" >> $GITHUB_OUTPUT
@@ -124,6 +86,6 @@ jobs:
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add docs/community-stats.zh.md docs/community-stats.md docs/community-stats.json docs/badges README.md README_CN.md
git add docs/ README.md README_CN.md
git diff --staged --quiet || git commit -m "chore: update community stats - ${{ steps.check_changes.outputs.change_reason }}"
git push

View File

@@ -1,8 +1,6 @@
# GitHub Actions Workflow for Plugin Release
# 插件发布工作流
# Plugin Release Workflow
#
# This workflow automates the release process for OpenWebUI plugins.
# 此工作流自动化 OpenWebUI 插件的发布流程。
#
# Triggers:
# - Push to main branch when plugins are modified (auto-release)
@@ -15,7 +13,7 @@
# 3. Creates a GitHub Release with plugin files as downloadable assets
# 4. Supports multiple plugin updates in a single release
name: Plugin Release / 插件发布
name: Plugin Release
on:
# Auto-trigger on push to main when plugins are modified
@@ -324,15 +322,14 @@ jobs:
- name: Generate release notes
id: notes
env:
VERSION: ${{ steps.version.outputs.version }}
TITLE: ${{ github.event.inputs.release_title }}
NOTES: ${{ github.event.inputs.release_notes }}
DETECTED_CHANGES: ${{ needs.check-changes.outputs.release_notes }}
COMMITS: ${{ steps.commits.outputs.commits }}
run: |
VERSION="${{ steps.version.outputs.version }}"
TITLE="${{ github.event.inputs.release_title }}"
NOTES="${{ github.event.inputs.release_notes }}"
DETECTED_CHANGES="${{ needs.check-changes.outputs.release_notes }}"
COMMITS="${{ steps.commits.outputs.commits }}"
echo "# ${VERSION} Release / 发布" > release_notes.md
echo "" >> release_notes.md
> release_notes.md
if [ -n "$TITLE" ]; then
echo "## $TITLE" >> release_notes.md
@@ -340,21 +337,21 @@ jobs:
fi
if [ -n "$DETECTED_CHANGES" ] && ! echo "$DETECTED_CHANGES" | grep -q "No changes detected"; then
echo "## What's Changed / 更新内容" >> release_notes.md
echo "## What's Changed" >> release_notes.md
echo "" >> release_notes.md
echo "$DETECTED_CHANGES" >> release_notes.md
echo "" >> release_notes.md
fi
if [ -n "$COMMITS" ]; then
echo "## Commits / 提交记录" >> release_notes.md
echo "## Commits" >> release_notes.md
echo "" >> release_notes.md
echo "$COMMITS" >> release_notes.md
echo "" >> release_notes.md
fi
if [ -n "$NOTES" ]; then
echo "## Additional Notes / 附加说明" >> release_notes.md
echo "## Additional Notes" >> release_notes.md
echo "" >> release_notes.md
echo "$NOTES" >> release_notes.md
echo "" >> release_notes.md
@@ -364,11 +361,11 @@ jobs:
cat >> release_notes.md << 'EOF'
## Download / 下载
## Download
📦 **Download the updated plugin files below** / 请在下方下载更新的插件文件
📦 **Download the updated plugin files below**
### Installation / 安装
### Installation
#### From OpenWebUI Community
1. Open OpenWebUI Admin Panel
@@ -376,7 +373,7 @@ jobs:
3. Search for the plugin name
4. Click Install
#### Manual Installation / 手动安装
#### Manual Installation
1. Download the plugin file (`.py`) from the assets below
2. Open OpenWebUI Admin Panel → Functions
3. Click "Create Function" → Import
@@ -384,8 +381,8 @@ jobs:
---
📚 [Documentation / 文档](https://fu-jie.github.io/awesome-openwebui/)
🐛 [Report Issues / 报告问题](https://github.com/Fu-Jie/awesome-openwebui/issues)
📚 [Documentation](https://fu-jie.github.io/openwebui-extensions/)
🐛 [Report Issues](https://github.com/Fu-Jie/openwebui-extensions/issues)
EOF
echo "=== Release Notes ==="

3
.gitignore vendored
View File

@@ -136,6 +136,9 @@ logs/
# Temporary files
*.tmp
*.temp
.temp/
.build/
# OpenWebUI specific
# Add any specific ignores for OpenWebUI plugins if needed
.git-worktrees/

7
.markdownlint.json Normal file
View File

@@ -0,0 +1,7 @@
{
"default": true,
"MD013": false,
"MD033": false,
"MD030": false,
"MD051": false
}

View File

@@ -1,6 +1,6 @@
# Contributing Guide
Thank you for your interest in **OpenWebUI Extras**!
Thank you for your interest in **OpenWebUI Extensions**!
## 🚀 How to Contribute

View File

@@ -1,6 +1,6 @@
# 贡献指南
感谢你对 **OpenWebUI Extras** 感兴趣!
感谢你对 **OpenWebUI Extensions** 感兴趣!
## 🚀 贡献流程

157
GEMINI.md Normal file
View File

@@ -0,0 +1,157 @@
# OpenWebUI Extensions — Gemini CLI Project Context
> This file is loaded automatically by Gemini CLI as project-level instructions.
> Full engineering spec: `.github/copilot-instructions.md`
---
## Project Overview
**openwebui-extensions** is a collection of OpenWebUI plugins authored by Fu-Jie.
Repository: `https://github.com/Fu-Jie/openwebui-extensions`
Plugin types: `actions` / `filters` / `pipes` / `pipelines` / `tools`
---
## Non-Negotiable Rules
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.
2. **No silent failures.** All errors must surface via `__event_emitter__` notification or backend `logging`.
3. **No hardcoded model IDs.** Default to the current conversation model; let `Valves` override.
4. **Chinese responses.** Reply in Simplified Chinese for all planning, explanations, and status summaries. English only for code, commit messages, and docstrings.
---
## Plugin File Contract
Every plugin MUST be a **single-file i18n** Python module:
```text
plugins/{type}/{name}/{name}.py ← single source file, built-in i18n
plugins/{type}/{name}/README.md ← English docs
plugins/{type}/{name}/README_CN.md ← Chinese docs
```
### Docstring (required fields)
```python
"""
title: Plugin Display Name
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
description: One-line description.
"""
```
### Required patterns
- `Valves(BaseModel)` with `UPPER_SNAKE_CASE` fields
- `_get_user_context(__user__)` — never access `__user__` directly
- `_get_chat_context(body, __metadata__)` — never infer IDs ad-hoc
- `_emit_status(emitter, msg, done)` / `_emit_notification(emitter, content, type)`
- Async I/O only — wrap sync calls with `asyncio.to_thread`
- `logging` for backend logs — no bare `print()` in production
---
## Antigravity Development Rules
When the user invokes antigravity mode (high-speed iteration), enforce these safeguards automatically:
| Rule | Detail |
|------|--------|
| Small reversible edits | One logical change per file per operation |
| Timeout guards | `asyncio.wait_for(..., timeout=2.0)` on all `__event_call__` JS executions |
| Path sandbox | Verify every workspace path stays inside the repo root before read/write |
| Source Sensing | Use `source-code-analyzer` skill for `../open-webui`, `../copilot-sdk` etc. `git pull` before analysis. |
| External Auth | **AUTHORIZED** to read (RO) from specified external paths (open-webui, copilot-sdk, etc.) for analysis. |
| Fallback chains | API upload → DB + local copy; never a single point of failure |
| Progressive status | `status(done=False)` at start, `status(done=True)` on end, `notification(error)` on failure |
| Validate before emit | Check `emitter is not None` before every `await emitter(...)` |
---
## File Creation & Delivery Protocol (3-Step)
1. `local write` — create artifact inside workspace scope
2. `publish_file_from_workspace(filename='...')` — migrate to OpenWebUI storage (S3-compatible)
3. Return `/api/v1/files/{id}/content` download link in Markdown
Set `skip_rag=true` metadata on generated downloadable artifacts.
---
## Copilot SDK Tool Definition (critical)
```python
from pydantic import BaseModel, Field
from copilot import define_tool
class MyToolParams(BaseModel):
query: str = Field(..., description="Search query")
my_tool = define_tool(
name="my_tool",
description="...",
params_type=MyToolParams, # REQUIRED — prevents empty schema hallucination
)(async_impl_fn)
```
---
## Streaming Output Format (OpenWebUI 0.8.x)
- Reasoning: `<think>\n...\n</think>\n` — close BEFORE normal content or tool cards
- 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`
- Escape ALL `"` inside `arguments`/`result` attributes as `&quot;`
- Status events via `__event_emitter__` — do NOT pollute the content stream with debug text
---
## Documentation Sync (when changing a plugin)
Must update ALL of these or the PR check fails:
1. `plugins/{type}/{name}/{name}.py` — version in docstring
2. `plugins/{type}/{name}/README.md` — version, What's New
3. `plugins/{type}/{name}/README_CN.md` — same
4. `docs/plugins/{type}/{name}.md` — mirror README
5. `docs/plugins/{type}/{name}.zh.md` — mirror README_CN
6. `docs/plugins/{type}/index.md` — version badge
7. `docs/plugins/{type}/index.zh.md` — version badge
---
## i18n & Language Standards
1. **Alignment**: Keep the number of supported languages in `TRANSLATIONS` consistent with major plugins (e.g., `smart-mind-map`).
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.
3. **Fallback Map**: Must include variant redirects (e.g., `es-MX` -> `es-ES`, `fr-CA` -> `fr-FR`).
4. **Tooltips**: All `description` fields in `Valves` must be **English only** to maintain clean UI.
---
## Commit Message Format
```text
type(scope): brief English description
- Key change 1
- Key change 2
```
Types: `feat` / `fix` / `docs` / `refactor` / `chore`
Scope: plugin folder name (e.g., `github-copilot-sdk`)
---
## Full Reference
`.github/copilot-instructions.md` — complete engineering specification (1000+ lines)
`.agent/workflows/plugin-development.md` — step-by-step development workflow
`.agent/rules/antigravity.md` — antigravity mode detailed rules
`docs/development/copilot-engineering-plan.md` — design baseline

122
README.md
View File

@@ -1,6 +1,6 @@
# OpenWebUI Extras
# OpenWebUI Extensions
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
English | [中文](./README_CN.md)
@@ -9,40 +9,86 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
<!-- STATS_START -->
## 📊 Community Stats
> 🕐 Auto-updated: 2026-02-07 17:12
>
> ![updated](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_updated.json&style=flat)
| 👤 Author | 👥 Followers | ⭐ Points | 🏆 Contributions |
|:---:|:---:|:---:|:---:|
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **204** | **257** | **41** |
| :---: | :---: | :---: | :---: |
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&style=flat) |
| 📝 Posts | ⬇️ Downloads | 👁️ Views | 👍 Upvotes | 💾 Saves |
|:---:|:---:|:---:|:---:|:---:|
| **20** | **3711** | **43662** | **220** | **256** |
| :---: | :---: | :---: | :---: | :---: |
| ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
### 🔥 Top 6 Popular Plugins
> 🕐 Auto-updated: 2026-02-07 17:12
| Rank | Plugin | Version | Downloads | Views | 📅 Updated |
| :---: | :--- | :---: | :---: | :---: | :---: |
| 🥇 | [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--27-gray?style=flat) |
| 🥈 | [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) |
| 🥉 | [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--27-gray?style=flat) |
| 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) |
| 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) |
| 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) |
| Rank | Plugin | Version | Downloads | Views | Updated |
|:---:|------|:---:|:---:|:---:|:---:|
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.2 | 883 | 7810 | 2026-01-28 |
| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.5.0 | 635 | 5880 | 2026-01-30 |
| 🥉 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 347 | 2686 | 2026-01-28 |
| 4⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.2.2 | 330 | 3436 | 2026-01-28 |
| 5⃣ | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 327 | 1520 | 2026-01-29 |
| 6⃣ | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | 1.2.4 | 294 | 4270 | 2026-01-29 |
### 📈 Total Downloads Trend
*See full stats in [Community Stats Report](./docs/community-stats.md)*
![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg)
*See full stats and charts in [Community Stats Report](./docs/community-stats.md)*
<!-- STATS_END -->
## 🌟 Star Features
### 1. [GitHub Copilot SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4)
**The ultimate autonomous Agent for OpenWebUI.** Transforming your LLM into a powerful OS-level engineer with native code execution, deep tool autonomy, and professional skill management.
> [!TIP]
> **No GitHub Copilot subscription required!** Supports **BYOK (Bring Your Own Key)** mode using your own OpenAI/Anthropic API keys.
#### 🚀 Key Leap (v0.9.0+)
- **🧩 Skills Revolution**: Native support for **SKILL directories** (scripts, templates, resources) coupled with a **Bidirectional Bridge** to OpenWebUI Workspace Skills.
- **🛡️ Secure Isolation**: Strict user/session-level **Workspace Sandboxing** with persistent configuration.
- **📊 Interactive Delivery**: Professional **File Delivery Protocol** for instant HTML artifacts and persistent downloadable results.
- **🛠️ Deterministic Toolchain**: Built-in specialized tools for skill lifecycles (`manage_skills`) and system optimization.
#### 📺 Demo: Visual Skills & Data Analysis
![GitHub Copilot SDK Skill Demo](https://github.com/Fu-Jie/openwebui-extensions/raw/main/docs/assets/videos/skill.gif)
> *In this demo, the Agent installs a visual enhancement skill and automatically generates an interactive dashboard from World Cup data.*
#### 🌟 Featured Real-World Cases
- **[GitHub Star Forecasting](./docs/plugins/pipes/star-prediction-example.md)**: Automatically parsing CSV data, writing analysis scripts, and generating interactive growth dashboards.
- **[Video Optimization](./docs/plugins/pipes/video-processing-example.md)**: Direct control of system-level tools (FFmpeg) to accelerate and compress media with professional color optimization.
### 2. [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a)
**Experience interactive thinking.** Seamlessly transforms complex chat sessions into structured, clickable mind maps for better visual modeling and rapid idea extraction.
### 3. [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/smart_infographic_ad6f0c7f)
**Professional data storytelling.** Converts raw information into sleek, boardroom-ready infographics powered by AntV, perfect for summarizing long-form content instantly.
### 4. [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315)
**High-fidelity reporting.** Export conversation history into professionally formatted Word documents with preserved headers, code blocks, and math formulas.
### 5. [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/async_context_compression_b1655bc8)
**Maximize your context window.** Intelligently compresses chat history using LLM logic to save tokens and costs while maintaining a high-quality reasoning chain.
## 📦 Project Contents
### 🧩 Plugins
<!-- markdownlint-disable MD033 -->
<details>
<summary><b>🧩 Plugins (Actions, Filters, Pipes, Pipelines)</b></summary>
Located in the `plugins/` directory, containing Python-based enhancements:
#### Actions
### Actions
- **Smart Mind Map** (`smart-mind-map`): Generates interactive mind maps from text.
- **Smart Infographic** (`infographic`): Transforms text into professional infographics using AntV.
@@ -51,33 +97,44 @@ Located in the `plugins/` directory, containing Python-based enhancements:
- **Export to Excel** (`export_to_excel`): Exports chat history to Excel files.
- **Export to Word** (`export_to_docx`): Exports chat history to Word documents.
#### Filters
### Filters
- **GitHub Copilot SDK Files Filter** (`github_copilot_sdk_files_filter`): Essential companion for Copilot SDK. Bypasses RAG to ensure full file accessibility for Agents.
- **Web Gemini Multimodal Filter** (`web_gemini_multimodel_filter`): Adds multimodal capabilities (PDF, Video, Office) to any model with intelligent routing.
- **Async Context Compression** (`async-context-compression`): Optimizes token usage via context compression.
- **Context Enhancement** (`context_enhancement_filter`): Enhances chat context.
- **Folder Memory** (`folder-memory`): Automatically extracts project rules from conversations and injects them into the folder's system prompt.
- **Markdown Normalizer** (`markdown_normalizer`): Fixes common Markdown formatting issues in LLM outputs.
#### Pipes
### Pipes
- **GitHub Copilot SDK** (`github-copilot-sdk`): Official GitHub Copilot SDK integration. Supports dynamic models, multi-turn conversation, streaming, multimodal input, and infinite sessions.
- **GitHub Copilot SDK** (`github-copilot-sdk`): Official GitHub Copilot SDK integration. Supports dynamic models (GPT-4o, Claude 3.5, o1), multi-turn conversation, streaming, and infinite sessions.
#### Pipelines
### Pipelines
- **MoE Prompt Refiner** (`moe_prompt_refiner`): Refines prompts for Mixture of Experts (MoE) summary requests to generate high-quality comprehensive reports.
### 🎯 Prompts
</details>
<!-- markdownlint-enable MD033 -->
Located in the `prompts/` directory, containing fine-tuned System Prompts:
<!-- markdownlint-disable MD033 -->
<details>
<summary><b>🎯 Prompts (System Prompts for various roles)</b></summary>
- **Coding**: Programming assistance prompts.
- **Marketing**: Marketing and copywriting prompts.
System Prompts are managed in the `docs/prompts/` directory:
- **[Prompt Library](./docs/prompts/library.md)**: A curated collection of fine-tuned prompts for Coding, Marketing, and Analysis.
</details>
<!-- markdownlint-enable MD033 -->
## 🛠️ Extensions
Standalone frontend extensions to supercharge your Open WebUI:
- **[Open WebUI Prompt Plus](https://github.com/Fu-Jie/open-webui-prompt-plus)**: An all-in-one prompt management suite featuring AI-powered prompt generation, spotlight-style quick search, and advanced category organization.
- **[Open WebUI Prompt Plus](https://github.com/Fu-Jie/open-webui-prompt-plus)**
[![Newsletter](https://img.shields.io/badge/OpenWebUI_Newsletter-Featured-blue?style=flat-square)](https://openwebui.com/blog/newsletter-january-28-2026): An all-in-one prompt management suite featuring AI-powered prompt generation, spotlight-style quick search, and advanced category organization.
## 📖 Documentation
@@ -131,10 +188,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbb-dev"><img src="https://avatars.githubusercontent.com/u/37469229?v=4?s=100" width="100px;" alt="rbb-dev"/><br /><sub><b>rbb-dev</b></sub></a><br /><a href="#ideas-rbb-dev" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/Fu-Jie/awesome-openwebui/commits?author=rbb-dev" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://trade.xyz/?ref=BZ1RJRXWO"><img src="https://avatars.githubusercontent.com/u/7317522?v=4?s=100" width="100px;" alt="Raxxoor"/><br /><sub><b>Raxxoor</b></sub></a><br /><a href="https://github.com/Fu-Jie/awesome-openwebui/issues?q=author%3Adhaern" title="Bug reports">🐛</a> <a href="#ideas-dhaern" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/i-iooi-i"><img src="https://avatars.githubusercontent.com/u/1827701?v=4?s=100" width="100px;" alt="ZOLO"/><br /><sub><b>ZOLO</b></sub></a><br /><a href="https://github.com/Fu-Jie/awesome-openwebui/issues?q=author%3Ai-iooi-i" title="Bug reports">🐛</a> <a href="#ideas-i-iooi-i" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbb-dev"><img src="https://avatars.githubusercontent.com/u/37469229?v=4?s=100" width="100px;" alt="rbb-dev"/><br /><sub><b>rbb-dev</b></sub></a><br /><a href="#ideas-rbb-dev" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/Fu-Jie/openwebui-extensions/commits?author=rbb-dev" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://trade.xyz/?ref=BZ1RJRXWO"><img src="https://avatars.githubusercontent.com/u/7317522?v=4?s=100" width="100px;" alt="Raxxoor"/><br /><sub><b>Raxxoor</b></sub></a><br /><a href="https://github.com/Fu-Jie/openwebui-extensions/issues?q=author%3Adhaern" title="Bug reports">🐛</a> <a href="#ideas-dhaern" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/i-iooi-i"><img src="https://avatars.githubusercontent.com/u/1827701?v=4?s=100" width="100px;" alt="ZOLO"/><br /><sub><b>ZOLO</b></sub></a><br /><a href="https://github.com/Fu-Jie/openwebui-extensions/issues?q=author%3Ai-iooi-i" title="Bug reports">🐛</a> <a href="#ideas-i-iooi-i" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://perso.crans.org/grande/"><img src="https://avatars.githubusercontent.com/u/469017?v=4?s=100" width="100px;" alt="Johan Grande"/><br /><sub><b>Johan Grande</b></sub></a><br /><a href="#ideas-nahoj" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abaroni"><img src="https://avatars.githubusercontent.com/u/21365486?v=4?s=100" width="100px;" alt="Alessandro Baroni"/><br /><sub><b>Alessandro Baroni</b></sub></a><br /><a href="#ideas-abaroni" title="Ideas, Planning, & Feedback">🤔</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,4 +1,4 @@
# OpenWebUI Extras
# OpenWebUI Extensions
[English](./README.md) | 中文
@@ -6,40 +6,86 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
<!-- STATS_START -->
## 📊 社区统计
> 🕐 自动更新于 2026-02-07 17:12
>
> ![updated_zh](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_updated_zh.json&style=flat)
| 👤 作者 | 👥 粉丝 | ⭐ 积分 | 🏆 贡献 |
|:---:|:---:|:---:|:---:|
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | **204** | **257** | **41** |
| :---: | :---: | :---: | :---: |
| [Fu-Jie](https://openwebui.com/u/Fu-Jie) | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) | ![contributions](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_contributions.json&style=flat) |
| 📝 发布 | ⬇️ 下载 | 👁️ 浏览 | 👍 点赞 | 💾 收藏 |
|:---:|:---:|:---:|:---:|:---:|
| **20** | **3711** | **43662** | **220** | **256** |
| :---: | :---: | :---: | :---: | :---: |
| ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
### 🔥 热门插件 Top 6
> 🕐 自动更新于 2026-02-07 17:12
| 排名 | 插件 | 版本 | 下载 | 浏览 | 📅 更新 |
| :---: | :--- | :---: | :---: | :---: | :---: |
| 🥇 | [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--27-gray?style=flat) |
| 🥈 | [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) |
| 🥉 | [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--27-gray?style=flat) |
| 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) |
| 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) |
| 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) |
| 排名 | 插件 | 版本 | 下载 | 浏览 | 更新日期 |
|:---:|------|:---:|:---:|:---:|:---:|
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | 0.9.2 | 883 | 7810 | 2026-01-28 |
| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | 1.5.0 | 635 | 5880 | 2026-01-30 |
| 🥉 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | 0.4.3 | 347 | 2686 | 2026-01-28 |
| 4⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | 1.2.2 | 330 | 3436 | 2026-01-28 |
| 5⃣ | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | 0.3.7 | 327 | 1520 | 2026-01-29 |
| 6⃣ | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | 1.2.4 | 294 | 4270 | 2026-01-29 |
### 📈 总下载量累计趋势
*完整统计请查看 [社区统计报告](./docs/community-stats.zh.md)*
![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg)
*完整统计与趋势图请查看 [社区统计报告](./docs/community-stats.zh.md)*
<!-- STATS_END -->
## 🌟 精选功能
### 1. [GitHub Copilot SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4)
**OpenWebUI 终极自主 Agent 增强。** 将 LLM 转化为具备 OS 级操作能力的专业工程师,支持原生代码执行、深度工具自治以及专业技能管理。
> [!TIP]
> **无需 GitHub Copilot 订阅!** 支持 **BYOK (Bring Your Own Key)** 模式,使用你自己的 OpenAI/Anthropic API Key。
#### 🚀 核心进化 (v0.9.0+)
- **🧩 技能革命**: 原生支持 **SKILL 目录**(含脚本、模板与资源),并实现与 OpenWebUI **工作区 > Skills** 的深度双向桥接。
- **🛡️ 安全沙箱**: 严格的用户/会话级 **工作区隔离** 与持久化配置环境。
- **📊 交互交付**: 专业 **文件交付协议**,支持即时预览交互式 HTML Artifacts 与持久化结果下载。
- **🛠️ 确定性工具链**: 内置 `manage_skills` 等专业工具,赋予 Agent 完整的技能生命周期管理能力。
#### 📺 演示:可视化技能与数据分析
![GitHub Copilot SDK 技能演示](https://github.com/Fu-Jie/openwebui-extensions/raw/main/docs/assets/videos/skill.gif)
> *在此演示中Agent 自动安装可视化增强技能,并根据世界杯表格数据瞬间生成交互式看板。*
#### 🌟 核心实战案例
- **[GitHub Star 增长预测](./docs/plugins/pipes/star-prediction-example.zh.md)**:自动解析 CSV 数据,编写 Python 分析脚本并生成动态增长看板。
- **[视频高质量转换与压缩](./docs/plugins/pipes/video-processing-example.zh.md)**:直接调用系统级 FFmpeg 工具,实现录屏的加速、缩放及双阶段色彩优化。
### 2. [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a)
**体验浸入式思维。** 将复杂的对话瞬间转化为结构化、可点击的交互式思维导图,助力知识建模与逻辑提取。
### 3. [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/smart_infographic_ad6f0c7f)
**专业数据叙事。** 将零散信息转化为精美的信息图表(由 AntV 驱动),一键生成学术/汇报级的可视化总结。
### 4. [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315)
**高保真文档导出。** 将对话历史导出为格式完美的 Word 文档完美保留标题、代码块、LaTeX 公式及 Mermaid 流程图。
### 5. [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) [![Market](https://img.shields.io/badge/Get-Market-blue?style=flat-square&logo=openwebui)](https://openwebui.com/posts/async_context_compression_b1655bc8)
**挑战 Token 極限。** 采用多专家异步压缩逻辑,在保持高吞吐量推理链的同时,大幅降低 Token 消耗。
## 📦 项目内容
### 🧩 插件 (Plugins)
<!-- markdownlint-disable MD033 -->
<details>
<summary><b>🧩 插件 (Actions, Filters, Pipes, Pipelines)</b></summary>
位于 `plugins/` 目录,包含各类 Python 编写的功能增强插件:
#### Actions (交互增强)
### Actions (交互增强)
- **Smart Mind Map** (`smart-mind-map`): 智能分析文本并生成交互式思维导图。
- **Smart Infographic** (`infographic`): 基于 AntV 的智能信息图生成工具。
@@ -48,42 +94,49 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
- **Export to Excel** (`export_to_excel`): 将对话内容导出为 Excel 文件。
- **Export to Word** (`export_to_docx`): 将对话内容导出为 Word 文档。
#### Filters (消息处理)
### Filters (消息处理)
- **GitHub Copilot SDK Files Filter** (`github_copilot_sdk_files_filter`): Copilot SDK 必备搭档。绕过 RAG确保 Agent 能真正看到你的每一个文件。
- **Web Gemini Multimodal Filter** (`web_gemini_multimodel_filter`): 为任意模型提供多模态能力PDF、Office、视频等支持智能路由。
- **Async Context Compression** (`async-context-compression`): 异步上下文压缩,优化 Token 使用。
- **Context Enhancement** (`context_enhancement_filter`): 上下文增强过滤器。
- **Folder Memory** (`folder-memory`): 自动从对话中提取项目规则并注入到文件夹系统提示词中。
- **Gemini Manifold Companion** (`gemini_manifold_companion`): Gemini Manifold 配套增强。
- **Gemini Multimodal Filter** (`web_gemini_multimodel_filter`): 为任意模型提供多模态能力PDF、Office、视频等支持智能路由和字幕精修。
- **Markdown Normalizer** (`markdown_normalizer`): 修复 LLM 输出中常见的 Markdown 格式问题。
- **Multi-Model Context Merger** (`multi_model_context_merger`): 自动合并并注入多模型回答的上下文。
#### Pipes (模型管道)
### Pipes (模型管道)
- **GitHub Copilot SDK** (`github-copilot-sdk`): GitHub Copilot SDK 官方集成。支持动态模型、多轮对话、流式输出、图片输入及无限会话。
- **Gemini Manifold** (`gemini_mainfold`): 集成 Gemini 模型的管道。
#### Pipelines (工作流管道)
### Pipelines (工作流管道)
- **MoE Prompt Refiner** (`moe_prompt_refiner`): 优化多模型 (MoE) 汇总请求的提示词,生成高质量的综合报告。
### 🎯 提示词 (Prompts)
</details>
<!-- markdownlint-enable MD033 -->
位于 `prompts/` 目录,包含精心调优的 System Prompts
<!-- markdownlint-disable MD033 -->
<details>
<summary><b>🎯 提示词 (Prompts - 多角色系统提示词)</b></summary>
- **Coding**: 编程辅助类提示词。
- **Marketing**: 营销文案类提示词。
位于 `docs/prompts/` 目录,包含精心调优的提示词集合:
每个提示词都独立保存为 Markdown 文件,可直接在 OpenWebUI 中使用
- **[Prompt Library](./docs/prompts/library.md)**: 编程、翻译、分析及营销等全领域提示词精选
</details>
<!-- markdownlint-enable MD033 -->
## 🛠️ 扩展 (Extensions)
Open WebUI 的前端增强扩展:
- **[Open WebUI Prompt Plus](https://github.com/Fu-Jie/open-webui-prompt-plus)**: 一站式提示词管理套件,支持 AI 提示词生成、Spotlight 风格快速搜索及高级分类管理。
- **[Open WebUI Prompt Plus](https://github.com/Fu-Jie/open-webui-prompt-plus)** [![Newsletter](https://img.shields.io/badge/OpenWebUI_Newsletter-Featured-blue?style=flat-square)](https://openwebui.com/blog/newsletter-january-28-2026)一站式提示词管理套件,支持 AI 提示词生成、Spotlight 风格快速搜索及高级分类管理。
## 📖 开发文档
<!-- markdownlint-disable MD033 -->
<details>
<summary><b>📚 官方开发与运营指南</b></summary>
位于 `docs/zh/` 目录:
- **[插件开发权威指南](./docs/zh/plugin_development_guide.md)** - 整合了入门教程、核心 SDK 详解及最佳实践的系统化指南。 ⭐
@@ -91,36 +144,11 @@ Open WebUI 的前端增强扩展:
更多示例请查看 `docs/examples/` 目录。
</details>
<!-- markdownlint-enable MD033 -->
## 🚀 快速开始
本项目是一个资源集合,无需安装 Python 环境。你只需要下载对应的文件并导入到你的 OpenWebUI 实例中即可。
### 使用提示词 (Prompts)
1.`/prompts` 目录中浏览并选择你感兴趣的提示词文件 (`.md`)。
2. 复制文件内容。
3. 在 OpenWebUI 聊天界面中,点击输入框上方的 "Prompt" 按钮。
4. 粘贴内容并保存。
### 使用插件 (Plugins)
1. **从 OpenWebUI 社区安装 (推荐)**:
- 访问我的主页: [Fu-Jie's Profile](https://openwebui.com/u/Fu-Jie)
- 浏览插件列表,选择你喜欢的插件。
- 点击 "Get" 按钮,将其直接导入到你的 OpenWebUI 实例中。
2. **手动安装**:
-`/plugins` 目录中浏览并下载你需要的插件文件 (`.py`)。
- 打开 OpenWebUI 的 **管理员面板 (Admin Panel)** -> **设置 (Settings)** -> **插件 (Plugins)**
- 点击上传按钮,选择刚才下载的 `.py` 文件。
- 上传成功后,刷新页面,你就可以在聊天设置或工具栏中启用该插件了。
### 贡献代码
如果你有优质的提示词或插件想要分享:
1. Fork 本仓库。
2. 将你的文件添加到对应的 `prompts/``plugins/` 目录。
3. 提交 Pull Request。
[贡献指南](./CONTRIBUTING_CN.md) | [更新日志](./CHANGELOG.md)

0
docs/.!55042!.DS_Store Normal file
View File

View File

@@ -6,7 +6,7 @@ The Chinese version (README_CN.md) MUST be translated based on this English vers
[Brief description of what the plugin does. Keep it concise and engaging.]
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.0.0 | **Project:** [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui) | **License:** MIT
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.0.0 | **Project:** [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) | **License:** MIT
## What's New
@@ -39,15 +39,15 @@ The Chinese version (README_CN.md) MUST be translated based on this English vers
## ⭐ Support
If this plugin has been useful, a star on [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui) is a big motivation for me. Thank you for the support.
If this plugin has been useful, a star on [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions) is a big motivation for me. Thank you for the support.
## Troubleshooting ❓
- **Plugin not working?**: Check if the filter/action is enabled in the model settings.
- **Debug Logs**: Enable `SHOW_DEBUG_LOG` in Valves and check the browser console (F12) for detailed logs.
- **Error Messages**: If you see an error, please copy the full error message and report it.
- **Submit an Issue**: If you encounter any problems, please submit an issue on GitHub: [Awesome OpenWebUI Issues](https://github.com/Fu-Jie/awesome-openwebui/issues)
- **Submit an Issue**: If you encounter any problems, please submit an issue on GitHub: [OpenWebUI Extensions Issues](https://github.com/Fu-Jie/openwebui-extensions/issues)
## Changelog
See the full history on GitHub: [Awesome OpenWebUI](https://github.com/Fu-Jie/awesome-openwebui)
See the full history on GitHub: [OpenWebUI Extensions](https://github.com/Fu-Jie/openwebui-extensions)

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

Binary file not shown.

View File

@@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"label": "downloads",
"message": "3.7k",
"message": "6.4k",
"color": "blue",
"namedLogo": "openwebui"
}

View File

@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "followers",
"message": "204",
"message": "295",
"color": "blue"
}

View File

@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "plugins",
"message": "20",
"message": "25",
"color": "green"
}

View File

@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "points",
"message": "257",
"message": "299",
"color": "orange"
}

View File

@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "upvotes",
"message": "220",
"message": "254",
"color": "brightgreen"
}

View File

@@ -1,32 +1,34 @@
{
"total_posts": 20,
"total_downloads": 3711,
"total_views": 43662,
"total_upvotes": 220,
"total_downvotes": 2,
"total_saves": 256,
"total_comments": 47,
"total_posts": 25,
"total_downloads": 6379,
"total_views": 67827,
"total_upvotes": 254,
"total_downvotes": 3,
"total_saves": 337,
"total_comments": 58,
"by_type": {
"post": 6,
"pipe": 1,
"action": 14,
"unknown": 4,
"filter": 1
"action": 12,
"filter": 4,
"prompt": 1,
"review": 1
},
"posts": [
{
"title": "Smart Mind Map",
"slug": "turn_any_text_into_beautiful_mind_maps_3094c59a",
"type": "action",
"version": "0.9.2",
"version": "1.0.0",
"author": "Fu-Jie",
"description": "Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge.",
"downloads": 883,
"views": 7810,
"upvotes": 22,
"saves": 48,
"comments": 13,
"downloads": 1328,
"views": 11410,
"upvotes": 23,
"saves": 59,
"comments": 15,
"created_at": "2025-12-30",
"updated_at": "2026-01-28",
"updated_at": "2026-02-27",
"url": "https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a"
},
{
@@ -36,45 +38,61 @@
"version": "1.5.0",
"author": "Fu-Jie",
"description": "AI-powered infographic generator based on AntV Infographic. Supports professional templates, auto-icon matching, and SVG/PNG downloads.",
"downloads": 635,
"views": 5880,
"upvotes": 24,
"saves": 33,
"downloads": 1076,
"views": 10746,
"upvotes": 25,
"saves": 40,
"comments": 10,
"created_at": "2025-12-28",
"updated_at": "2026-01-30",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/smart_infographic_ad6f0c7f"
},
{
"title": "Export to Word (Enhanced)",
"title": "Markdown Normalizer",
"slug": "markdown_normalizer_baaa8732",
"type": "filter",
"version": "1.2.7",
"author": "Fu-Jie",
"description": "A content normalizer filter that fixes common Markdown formatting issues in LLM outputs, such as broken code blocks, LaTeX formulas, and list formatting. Including LaTeX command protection.",
"downloads": 609,
"views": 6795,
"upvotes": 18,
"saves": 37,
"comments": 5,
"created_at": "2026-01-12",
"updated_at": "2026-02-27",
"url": "https://openwebui.com/posts/markdown_normalizer_baaa8732"
},
{
"title": "Export to Word Enhanced",
"slug": "export_to_word_enhanced_formatting_fca6a315",
"type": "action",
"version": "0.4.3",
"version": "0.4.4",
"author": "Fu-Jie",
"description": "Export current conversation from Markdown to Word (.docx) with Mermaid diagrams rendered client-side (Mermaid.js, SVG+PNG), LaTeX math, real hyperlinks, improved tables, syntax highlighting, and blockquote support.",
"downloads": 347,
"views": 2686,
"upvotes": 14,
"saves": 26,
"comments": 2,
"downloads": 578,
"views": 4611,
"upvotes": 16,
"saves": 30,
"comments": 5,
"created_at": "2026-01-03",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315"
},
{
"title": "Async Context Compression",
"slug": "async_context_compression_b1655bc8",
"type": "action",
"version": "1.2.2",
"type": "filter",
"version": "1.3.0",
"author": "Fu-Jie",
"description": "Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.",
"downloads": 330,
"views": 3436,
"upvotes": 14,
"saves": 33,
"downloads": 559,
"views": 5452,
"upvotes": 15,
"saves": 41,
"comments": 0,
"created_at": "2025-11-08",
"updated_at": "2026-01-28",
"updated_at": "2026-02-21",
"url": "https://openwebui.com/posts/async_context_compression_b1655bc8"
},
{
@@ -84,30 +102,30 @@
"version": "0.3.7",
"author": "Fu-Jie",
"description": "Extracts tables from chat messages and exports them to Excel (.xlsx) files with smart formatting.",
"downloads": 327,
"views": 1520,
"upvotes": 7,
"saves": 6,
"downloads": 492,
"views": 2693,
"upvotes": 10,
"saves": 8,
"comments": 0,
"created_at": "2025-05-30",
"updated_at": "2026-01-29",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d"
},
{
"title": "Markdown Normalizer",
"slug": "markdown_normalizer_baaa8732",
"type": "action",
"version": "1.2.4",
"author": "Fu-Jie",
"description": "A content normalizer filter that fixes common Markdown formatting issues in LLM outputs, such as broken code blocks, LaTeX formulas, and list formatting.",
"downloads": 294,
"views": 4270,
"upvotes": 17,
"saves": 27,
"comments": 5,
"created_at": "2026-01-12",
"updated_at": "2026-01-29",
"url": "https://openwebui.com/posts/markdown_normalizer_baaa8732"
"title": "AI Task Instruction Generator",
"slug": "ai_task_instruction_generator_9bab8b37",
"type": "prompt",
"version": "",
"author": "",
"description": "",
"downloads": 473,
"views": 5498,
"upvotes": 9,
"saves": 14,
"comments": 0,
"created_at": "2026-01-28",
"updated_at": "2026-01-28",
"url": "https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37"
},
{
"title": "Flash Card",
@@ -116,30 +134,30 @@
"version": "0.2.4",
"author": "Fu-Jie",
"description": "Quickly generates beautiful flashcards from text, extracting key points and categories.",
"downloads": 213,
"views": 3247,
"downloads": 285,
"views": 4128,
"upvotes": 13,
"saves": 14,
"saves": 18,
"comments": 2,
"created_at": "2025-12-30",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/flash_card_65a2ea8f"
},
{
"title": "AI Task Instruction Generator",
"slug": "ai_task_instruction_generator_9bab8b37",
"type": "unknown",
"version": "",
"author": "",
"description": "",
"downloads": 153,
"views": 2234,
"upvotes": 8,
"saves": 3,
"comments": 0,
"created_at": "2026-01-28",
"updated_at": "2026-01-28",
"url": "https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37"
"title": "GitHub Copilot Official SDK Pipe",
"slug": "github_copilot_official_sdk_pipe_ce96f7b4",
"type": "pipe",
"version": "0.9.0",
"author": "Fu-Jie",
"description": "Integrate GitHub Copilot SDK. Supports dynamic models, multi-turn conversation, streaming, multimodal input, infinite sessions, bidirectional OpenWebUI Skills bridge, and manage_skills tool.",
"downloads": 263,
"views": 4106,
"upvotes": 14,
"saves": 10,
"comments": 6,
"created_at": "2026-01-26",
"updated_at": "2026-02-27",
"url": "https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4"
},
{
"title": "Deep Dive",
@@ -148,47 +166,31 @@
"version": "1.0.0",
"author": "Fu-Jie",
"description": "A comprehensive thinking lens that dives deep into any content - from context to logic, insights, and action paths.",
"downloads": 134,
"views": 1162,
"downloads": 204,
"views": 1631,
"upvotes": 6,
"saves": 11,
"saves": 13,
"comments": 0,
"created_at": "2026-01-08",
"updated_at": "2026-01-08",
"url": "https://openwebui.com/posts/deep_dive_c0b846e4"
},
{
"title": "导出为 Word (增强版)",
"title": "导出为Word增强版",
"slug": "导出为_word_支持公式流程图表格和代码块_8a6306c0",
"type": "action",
"version": "0.4.3",
"version": "0.4.4",
"author": "Fu-Jie",
"description": "将对话导出为 Word (.docx),支持 Mermaid 图表 (客户端渲染 SVG+PNG)、LaTeX 数学公式、真实超链接、增强表格格式、代码高亮和引用块。",
"downloads": 119,
"views": 2111,
"upvotes": 13,
"saves": 6,
"downloads": 153,
"views": 2631,
"upvotes": 14,
"saves": 7,
"comments": 4,
"created_at": "2026-01-04",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0"
},
{
"title": "智能信息图",
"slug": "智能信息图_e04a48ff",
"type": "action",
"version": "1.5.0",
"author": "Fu-Jie",
"description": "基于 AntV Infographic 的智能信息图生成插件。支持多种专业模板,自动图标匹配,并提供 SVG/PNG 下载功能。",
"downloads": 56,
"views": 1006,
"upvotes": 10,
"saves": 1,
"comments": 0,
"created_at": "2025-12-28",
"updated_at": "2026-01-29",
"url": "https://openwebui.com/posts/智能信息图_e04a48ff"
},
{
"title": "📂 Folder Memory Auto-Evolving Project Context",
"slug": "folder_memory_auto_evolving_project_context_4a9875b2",
@@ -196,30 +198,46 @@
"version": "0.1.0",
"author": "Fu-Jie",
"description": "Automatically extracts project rules from conversations and injects them into the folder's system prompt.",
"downloads": 56,
"views": 1209,
"upvotes": 6,
"saves": 8,
"downloads": 99,
"views": 1839,
"upvotes": 7,
"saves": 11,
"comments": 0,
"created_at": "2026-01-20",
"updated_at": "2026-01-20",
"url": "https://openwebui.com/posts/folder_memory_auto_evolving_project_context_4a9875b2"
},
{
"title": "GitHub Copilot Official SDK Pipe",
"slug": "github_copilot_official_sdk_pipe_ce96f7b4",
"type": "pipe",
"version": "0.3.0",
"title": "智能信息图",
"slug": "智能信息图_e04a48ff",
"type": "action",
"version": "1.5.0",
"author": "Fu-Jie",
"description": "Integrate GitHub Copilot SDK. Supports dynamic models, multi-turn conversation, streaming, multimodal input, infinite sessions, and frontend debug logging.",
"downloads": 52,
"views": 1882,
"upvotes": 12,
"saves": 6,
"comments": 1,
"created_at": "2026-01-26",
"updated_at": "2026-02-07",
"url": "https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4"
"description": "基于 AntV Infographic 的智能信息图生成插件。支持多种专业模板,自动图标匹配,并提供 SVG/PNG 下载功能。",
"downloads": 65,
"views": 1304,
"upvotes": 10,
"saves": 1,
"comments": 0,
"created_at": "2025-12-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/智能信息图_e04a48ff"
},
{
"title": "GitHub Copilot SDK Files Filter",
"slug": "github_copilot_sdk_files_filter_403a62ee",
"type": "filter",
"version": "0.1.3",
"author": "Fu-Jie",
"description": "A specialized filter to bypass OpenWebUI's default RAG for GitHub Copilot SDK models. It moves uploaded files to a safe location ('copilot_files') so the Copilot Pipe can process them natively without interference.",
"downloads": 54,
"views": 2098,
"upvotes": 3,
"saves": 1,
"comments": 0,
"created_at": "2026-02-09",
"updated_at": "2026-02-25",
"url": "https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee"
},
{
"title": "思维导图",
@@ -228,13 +246,13 @@
"version": "0.9.2",
"author": "Fu-Jie",
"description": "智能分析文本内容,生成交互式思维导图,帮助用户结构化和可视化知识。",
"downloads": 37,
"views": 564,
"downloads": 45,
"views": 691,
"upvotes": 6,
"saves": 2,
"comments": 0,
"created_at": "2025-12-31",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b"
},
{
@@ -244,13 +262,13 @@
"version": "1.2.2",
"author": "Fu-Jie",
"description": "通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。",
"downloads": 31,
"views": 628,
"downloads": 38,
"views": 783,
"upvotes": 7,
"saves": 4,
"saves": 5,
"comments": 0,
"created_at": "2025-11-08",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/异步上下文压缩_5c0617cb"
},
{
@@ -260,13 +278,13 @@
"version": "0.2.4",
"author": "Fu-Jie",
"description": "快速将文本提炼为精美的学习记忆卡片,支持核心要点提取与分类。",
"downloads": 27,
"views": 661,
"upvotes": 8,
"downloads": 32,
"views": 830,
"upvotes": 7,
"saves": 1,
"comments": 0,
"created_at": "2025-12-30",
"updated_at": "2026-01-28",
"updated_at": "2026-02-13",
"url": "https://openwebui.com/posts/闪记卡生成插件_4a31eac3"
},
{
@@ -276,8 +294,8 @@
"version": "1.0.0",
"author": "Fu-Jie",
"description": "全方位的思维透镜 —— 从背景全景到逻辑脉络,从深度洞察到行动路径。",
"downloads": 17,
"views": 400,
"downloads": 26,
"views": 581,
"upvotes": 5,
"saves": 1,
"comments": 0,
@@ -286,16 +304,80 @@
"url": "https://openwebui.com/posts/精读_99830b0f"
},
{
"title": "🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager",
"slug": "open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e",
"type": "unknown",
"title": "🚀 GitHub Copilot SDK Pipe v0.9.0: Copilot SDK Skills Core Capabilities & Extended Delivery",
"slug": "github_copilot_sdk_pipe_v090_copilot_sdk_skills_co_99a42452",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 1429,
"views": 7,
"upvotes": 0,
"saves": 0,
"comments": 0,
"created_at": "2026-02-27",
"updated_at": "2026-02-27",
"url": "https://openwebui.com/posts/github_copilot_sdk_pipe_v090_copilot_sdk_skills_co_99a42452"
},
{
"title": "🚀 GitHub Copilot SDK Pipe v0.8.0: Conditional Tool Filtering & Publish Reliability 🎛️",
"slug": "github_copilot_sdk_pipe_v080_conditional_tool_filt_a5a3322d",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 1059,
"upvotes": 2,
"saves": 2,
"comments": 0,
"created_at": "2026-02-25",
"updated_at": "2026-02-25",
"url": "https://openwebui.com/posts/github_copilot_sdk_pipe_v080_conditional_tool_filt_a5a3322d"
},
{
"title": "🚀 GitHub Copilot SDK Pipe v0.7.0: Native Tool UI & Zero-Config CLI 🛠️",
"slug": "github_copilot_sdk_pipe_v070_native_tool_ui_zero_c_4af38131",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 2162,
"upvotes": 7,
"saves": 2,
"comments": 1,
"created_at": "2026-02-22",
"updated_at": "2026-02-22",
"url": "https://openwebui.com/posts/github_copilot_sdk_pipe_v070_native_tool_ui_zero_c_4af38131"
},
{
"title": "🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks",
"slug": "github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 2257,
"upvotes": 7,
"saves": 4,
"comments": 0,
"created_at": "2026-02-10",
"updated_at": "2026-02-10",
"url": "https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293"
},
{
"title": "🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager",
"slug": "open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 1839,
"upvotes": 12,
"saves": 17,
"saves": 19,
"comments": 8,
"created_at": "2026-01-25",
"updated_at": "2026-01-28",
@@ -304,12 +386,12 @@
{
"title": "Review of Claude Haiku 4.5",
"slug": "review_of_claude_haiku_45_41b0db39",
"type": "unknown",
"type": "review",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 135,
"views": 234,
"upvotes": 2,
"saves": 0,
"comments": 0,
@@ -320,14 +402,14 @@
{
"title": " 🛠️ Debug Open WebUI Plugins in Your Browser",
"slug": "debug_open_webui_plugins_in_your_browser_81bf7960",
"type": "unknown",
"type": "post",
"version": "",
"author": "",
"description": "",
"downloads": 0,
"views": 1392,
"upvotes": 14,
"saves": 9,
"views": 1502,
"upvotes": 16,
"saves": 11,
"comments": 2,
"created_at": "2026-01-10",
"updated_at": "2026-01-10",
@@ -339,11 +421,11 @@
"name": "Fu-Jie",
"profile_url": "https://openwebui.com/u/Fu-Jie",
"profile_image": "https://community.s3.openwebui.com/uploads/users/b15d1348-4347-42b4-b815-e053342d6cb0/profile_d9510745-4bd4-4f8f-a997-4a21847d9300.webp",
"followers": 204,
"following": 4,
"total_points": 257,
"post_points": 218,
"comment_points": 39,
"contributions": 41
"followers": 295,
"following": 6,
"total_points": 299,
"post_points": 251,
"comment_points": 48,
"contributions": 54
}
}

View File

@@ -1,46 +1,63 @@
# 📊 OpenWebUI Community Stats Report
> 📅 Updated: 2026-02-07 17:12
> ![updated](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_updated.json&style=flat)
### 📈 Total Downloads Trend
![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg)
> *Blue: Downloads | Purple: Views (Real-time dynamic)*
### 📂 Content Distribution
![Distribution](https://kroki.io/mermaid/svg/eNpNi0EOQDAQRfdOMekNiFhYO4CFCyBDflI6aafE7Sld-Lv38p-ASaGWyfQ2rthpuIQDdQjqMUWF201Bz4y4oIZaajJCOGH54Ti_1ySqzyywyj6ZOhfebaK_xvMBPl9xA49YJGU=)
## 📈 Overview
| Metric | Value |
|------|------|
| 📝 Total Posts | 20 |
| ⬇️ Total Downloads | 3711 |
| 👁️ Total Views | 43662 |
| 👍 Total Upvotes | 220 |
| 💾 Total Saves | 256 |
| 💬 Total Comments | 47 |
| 📝 Total Posts | ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) |
| ⬇️ Total Downloads | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) |
| 👁️ Total Views | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) |
| 👍 Total Upvotes | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) |
| 💾 Total Saves | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
| ⭐ Author Points | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) |
| 👥 Followers | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) |
## 📂 By Type
- **pipe**: 1
- **action**: 14
- **unknown**: 4
- **filter**: 1
- ![post](https://img.shields.io/badge/post-6-blue)
- ![pipe](https://img.shields.io/badge/pipe-1-blueviolet)
- ![action](https://img.shields.io/badge/action-12-orange)
- ![filter](https://img.shields.io/badge/filter-4-brightgreen)
- ![prompt](https://img.shields.io/badge/prompt-1-lightgrey)
- ![review](https://img.shields.io/badge/review-1-yellow)
## 📋 Posts List
| Rank | Title | Type | Version | Downloads | Views | Upvotes | Saves | Updated |
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 883 | 7810 | 22 | 48 | 2026-01-28 |
| 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.5.0 | 635 | 5880 | 24 | 33 | 2026-01-30 |
| 3 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 347 | 2686 | 14 | 26 | 2026-01-28 |
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.2.2 | 330 | 3436 | 14 | 33 | 2026-01-28 |
| 5 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 327 | 1520 | 7 | 6 | 2026-01-29 |
| 6 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.4 | 294 | 4270 | 17 | 27 | 2026-01-29 |
| 7 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 213 | 3247 | 13 | 14 | 2026-01-28 |
| 8 | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | unknown | | 153 | 2234 | 8 | 3 | 2026-01-28 |
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 134 | 1162 | 6 | 11 | 2026-01-08 |
| 10 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 119 | 2111 | 13 | 6 | 2026-01-28 |
| 11 | [智能信息图](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.5.0 | 56 | 1006 | 10 | 1 | 2026-01-29 |
| 12 | [📂 Folder Memory Auto-Evolving Project Context](https://openwebui.com/posts/folder_memory_auto_evolving_project_context_4a9875b2) | filter | 0.1.0 | 56 | 1209 | 6 | 8 | 2026-01-20 |
| 13 | [GitHub Copilot Official SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) | pipe | 0.3.0 | 52 | 1882 | 12 | 6 | 2026-02-07 |
| 14 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.2 | 37 | 564 | 6 | 2 | 2026-01-28 |
| 15 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.2.2 | 31 | 628 | 7 | 4 | 2026-01-28 |
| 16 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 27 | 661 | 8 | 1 | 2026-01-28 |
| 17 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 17 | 400 | 5 | 1 | 2026-01-08 |
| 18 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | unknown | | 0 | 1429 | 12 | 17 | 2026-01-28 |
| 19 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 135 | 2 | 0 | 2026-01-14 |
| 20 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1392 | 14 | 9 | 2026-01-10 |
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_dl.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_vw.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_up.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_sv.json&style=flat) | 2026-02-27 |
| 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![post_376135b87514e63570283b2057459b1f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_dl.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_vw.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_up.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_sv.json&style=flat) | 2026-02-13 |
| 3 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | filter | ![v](https://img.shields.io/badge/v-1.2.7-blue?style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_dl.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_vw.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_up.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_sv.json&style=flat) | 2026-02-27 |
| 4 | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![post_dc072f01690dc8293384153dc0231d05_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_dl.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_vw.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_up.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_sv.json&style=flat) | 2026-02-13 |
| 5 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | ![v](https://img.shields.io/badge/v-1.3.0-blue?style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_dl.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_vw.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_up.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_sv.json&style=flat) | 2026-02-21 |
| 6 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | ![v](https://img.shields.io/badge/v-0.3.7-blue?style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_dl.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_vw.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_up.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_sv.json&style=flat) | 2026-02-13 |
| 7 | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | prompt | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_dl.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_vw.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_up.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_sv.json&style=flat) | 2026-01-28 |
| 8 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | ![v](https://img.shields.io/badge/v-0.2.4-blue?style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_dl.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_vw.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_up.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_sv.json&style=flat) | 2026-02-13 |
| 9 | [GitHub Copilot Official SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) | pipe | ![v](https://img.shields.io/badge/v-0.9.0-blue?style=flat) | ![post_aef940e01073e811a311c3a443d9c149_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_dl.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_vw.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_up.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_sv.json&style=flat) | 2026-02-27 |
| 10 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_dl.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_vw.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_up.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_sv.json&style=flat) | 2026-01-08 |
| 11 | [导出为Word增强版](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_dl.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_vw.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_up.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_sv.json&style=flat) | 2026-02-13 |
| 12 | [📂 Folder Memory Auto-Evolving Project Context](https://openwebui.com/posts/folder_memory_auto_evolving_project_context_4a9875b2) | filter | ![v](https://img.shields.io/badge/v-0.1.0-blue?style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_dl.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_vw.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_up.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_sv.json&style=flat) | 2026-01-20 |
| 13 | [智能信息图](https://openwebui.com/posts/智能信息图_e04a48ff) | action | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_dl.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_vw.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_up.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_sv.json&style=flat) | 2026-02-13 |
| 14 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | ![v](https://img.shields.io/badge/v-0.1.3-blue?style=flat) | ![post_68081377a06a5746efe798136a72c6b6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_dl.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_vw.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_up.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_sv.json&style=flat) | 2026-02-25 |
| 15 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | ![v](https://img.shields.io/badge/v-0.9.2-blue?style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_dl.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_vw.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_up.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_sv.json&style=flat) | 2026-02-13 |
| 16 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | ![v](https://img.shields.io/badge/v-1.2.2-blue?style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_dl.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_vw.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_up.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_sv.json&style=flat) | 2026-02-13 |
| 17 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | ![v](https://img.shields.io/badge/v-0.2.4-blue?style=flat) | ![post_c68a2593e76ec324361358575b6501de_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_dl.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_vw.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_up.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_sv.json&style=flat) | 2026-02-13 |
| 18 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_dl.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_vw.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_up.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_sv.json&style=flat) | 2026-01-08 |
| 19 | [🚀 GitHub Copilot SDK Pipe v0.9.0: Copilot SDK Skills Core Capabilities & Extended Delivery](https://openwebui.com/posts/github_copilot_sdk_pipe_v090_copilot_sdk_skills_co_99a42452) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_dl.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_vw.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_up.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_sv.json&style=flat) | 2026-02-27 |
| 20 | [🚀 GitHub Copilot SDK Pipe v0.8.0: Conditional Tool Filtering & Publish Reliability 🎛️](https://openwebui.com/posts/github_copilot_sdk_pipe_v080_conditional_tool_filt_a5a3322d) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_dl.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_vw.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_up.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_sv.json&style=flat) | 2026-02-25 |
| 21 | [🚀 GitHub Copilot SDK Pipe v0.7.0: Native Tool UI & Zero-Config CLI 🛠️](https://openwebui.com/posts/github_copilot_sdk_pipe_v070_native_tool_ui_zero_c_4af38131) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_dl.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_vw.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_up.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_sv.json&style=flat) | 2026-02-22 |
| 22 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_dl.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_vw.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_up.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_sv.json&style=flat) | 2026-02-10 |
| 23 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_858cb162732370288ce024b4f7944f69_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_dl.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_vw.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_up.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_sv.json&style=flat) | 2026-01-28 |
| 24 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | review | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_dl.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_vw.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_up.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_sv.json&style=flat) | 2026-01-14 |
| 25 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_dl.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_vw.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_up.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_sv.json&style=flat) | 2026-01-10 |

View File

@@ -1,46 +1,63 @@
# 📊 OpenWebUI 社区统计报告
> 📅 更新时间: 2026-02-07 17:12
> ![updated_zh](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_updated_zh.json&style=flat)
### 📈 总下载量累计趋势
![Activity](https://gist.githubusercontent.com/Fu-Jie/db3d95687075a880af6f1fba76d679c6/raw/chart.svg)
> *蓝色: 总下载量 | 紫色: 总浏览量 (实时动态生成)*
### 📂 内容分类占比 (Distribution)
![Distribution](https://kroki.io/mermaid/svg/eNpNi0EOQDAQRfdOMekNiFhYO4CFCyBDflI6aafE7Sld-Lv38p-ASaGWyfQ2rthpuIQDdQjqMUWF201Bz4y4oIZaajJCOGH54Ti_1ySqzyywyj6ZOhfebaK_xvMBPl9xA49YJGU=)
## 📈 总览
| 指标 | 数值 |
|------|------|
| 📝 发布数量 | 20 |
| ⬇️ 总下载量 | 3711 |
| 👁️ 总浏览量 | 43662 |
| 👍 总点赞数 | 220 |
| 💾 总收藏数 | 256 |
| 💬 总评论数 | 47 |
| 📝 发布数量 | ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) |
| ⬇️ 总下载量 | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) |
| 👁️ 总浏览量 | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) |
| 👍 总点赞数 | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) |
| 💾 总收藏数 | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
| ⭐ 作者总积分 | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) |
| 👥 粉丝数量 | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) |
## 📂 按类型分类
- **pipe**: 1
- **action**: 14
- **unknown**: 4
- **filter**: 1
- ![post](https://img.shields.io/badge/post-6-blue)
- ![pipe](https://img.shields.io/badge/pipe-1-blueviolet)
- ![action](https://img.shields.io/badge/action-12-orange)
- ![filter](https://img.shields.io/badge/filter-4-brightgreen)
- ![prompt](https://img.shields.io/badge/prompt-1-lightgrey)
- ![review](https://img.shields.io/badge/review-1-yellow)
## 📋 发布列表
| 排名 | 标题 | 类型 | 版本 | 下载 | 浏览 | 点赞 | 收藏 | 更新日期 |
|:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 883 | 7810 | 22 | 48 | 2026-01-28 |
| 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.5.0 | 635 | 5880 | 24 | 33 | 2026-01-30 |
| 3 | [Export to Word (Enhanced)](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.3 | 347 | 2686 | 14 | 26 | 2026-01-28 |
| 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | action | 1.2.2 | 330 | 3436 | 14 | 33 | 2026-01-28 |
| 5 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | 0.3.7 | 327 | 1520 | 7 | 6 | 2026-01-29 |
| 6 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | action | 1.2.4 | 294 | 4270 | 17 | 27 | 2026-01-29 |
| 7 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | 0.2.4 | 213 | 3247 | 13 | 14 | 2026-01-28 |
| 8 | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | unknown | | 153 | 2234 | 8 | 3 | 2026-01-28 |
| 9 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | 1.0.0 | 134 | 1162 | 6 | 11 | 2026-01-08 |
| 10 | [导出为 Word (增强版)](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | 0.4.3 | 119 | 2111 | 13 | 6 | 2026-01-28 |
| 11 | [智能信息图](https://openwebui.com/posts/智能信息图_e04a48ff) | action | 1.5.0 | 56 | 1006 | 10 | 1 | 2026-01-29 |
| 12 | [📂 Folder Memory Auto-Evolving Project Context](https://openwebui.com/posts/folder_memory_auto_evolving_project_context_4a9875b2) | filter | 0.1.0 | 56 | 1209 | 6 | 8 | 2026-01-20 |
| 13 | [GitHub Copilot Official SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) | pipe | 0.3.0 | 52 | 1882 | 12 | 6 | 2026-02-07 |
| 14 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | 0.9.2 | 37 | 564 | 6 | 2 | 2026-01-28 |
| 15 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.2.2 | 31 | 628 | 7 | 4 | 2026-01-28 |
| 16 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 27 | 661 | 8 | 1 | 2026-01-28 |
| 17 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 17 | 400 | 5 | 1 | 2026-01-08 |
| 18 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | unknown | | 0 | 1429 | 12 | 17 | 2026-01-28 |
| 19 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | unknown | | 0 | 135 | 2 | 0 | 2026-01-14 |
| 20 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | unknown | | 0 | 1392 | 14 | 9 | 2026-01-10 |
| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_dl.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_vw.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_up.json&style=flat) | ![post_207cd433d27fdd853ccbfa941e6fa67f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_207cd433d27fdd853ccbfa941e6fa67f_sv.json&style=flat) | 2026-02-27 |
| 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![post_376135b87514e63570283b2057459b1f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_dl.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_vw.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_up.json&style=flat) | ![post_376135b87514e63570283b2057459b1f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_376135b87514e63570283b2057459b1f_sv.json&style=flat) | 2026-02-13 |
| 3 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | filter | ![v](https://img.shields.io/badge/v-1.2.7-blue?style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_dl.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_vw.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_up.json&style=flat) | ![post_a963da7c5d914310e7026b8c8a6635b0_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a963da7c5d914310e7026b8c8a6635b0_sv.json&style=flat) | 2026-02-27 |
| 4 | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![post_dc072f01690dc8293384153dc0231d05_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_dl.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_vw.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_up.json&style=flat) | ![post_dc072f01690dc8293384153dc0231d05_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_dc072f01690dc8293384153dc0231d05_sv.json&style=flat) | 2026-02-13 |
| 5 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | ![v](https://img.shields.io/badge/v-1.3.0-blue?style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_dl.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_vw.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_up.json&style=flat) | ![post_0640a7ef0970872217cb939f2ba9c12c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0640a7ef0970872217cb939f2ba9c12c_sv.json&style=flat) | 2026-02-21 |
| 6 | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | action | ![v](https://img.shields.io/badge/v-0.3.7-blue?style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_dl.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_vw.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_up.json&style=flat) | ![post_c5ae05d46c7b999a1e36ca1457f1926b_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5ae05d46c7b999a1e36ca1457f1926b_sv.json&style=flat) | 2026-02-13 |
| 7 | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) | prompt | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_dl.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_vw.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_up.json&style=flat) | ![post_19f469a02b32d21f86b16d1395a81317_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_19f469a02b32d21f86b16d1395a81317_sv.json&style=flat) | 2026-01-28 |
| 8 | [Flash Card](https://openwebui.com/posts/flash_card_65a2ea8f) | action | ![v](https://img.shields.io/badge/v-0.2.4-blue?style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_dl.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_vw.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_up.json&style=flat) | ![post_5cf7a5dad74ef15ee4ffc6fe10da8213_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_5cf7a5dad74ef15ee4ffc6fe10da8213_sv.json&style=flat) | 2026-02-13 |
| 9 | [GitHub Copilot Official SDK Pipe](https://openwebui.com/posts/github_copilot_official_sdk_pipe_ce96f7b4) | pipe | ![v](https://img.shields.io/badge/v-0.9.0-blue?style=flat) | ![post_aef940e01073e811a311c3a443d9c149_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_dl.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_vw.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_up.json&style=flat) | ![post_aef940e01073e811a311c3a443d9c149_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_aef940e01073e811a311c3a443d9c149_sv.json&style=flat) | 2026-02-27 |
| 10 | [Deep Dive](https://openwebui.com/posts/deep_dive_c0b846e4) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_dl.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_vw.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_up.json&style=flat) | ![post_78e3480de4e6bd4615498495c5d15979_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_78e3480de4e6bd4615498495c5d15979_sv.json&style=flat) | 2026-01-08 |
| 11 | [导出为Word增强版](https://openwebui.com/posts/导出为_word_支持公式流程图表格和代码块_8a6306c0) | action | ![v](https://img.shields.io/badge/v-0.4.4-blue?style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_dl.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_vw.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_up.json&style=flat) | ![post_fc4cbdf0eb78bd98c2ed7650d459b59e_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fc4cbdf0eb78bd98c2ed7650d459b59e_sv.json&style=flat) | 2026-02-13 |
| 12 | [📂 Folder Memory Auto-Evolving Project Context](https://openwebui.com/posts/folder_memory_auto_evolving_project_context_4a9875b2) | filter | ![v](https://img.shields.io/badge/v-0.1.0-blue?style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_dl.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_vw.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_up.json&style=flat) | ![post_a125b3a3702a07c86c77668dcede2149_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_a125b3a3702a07c86c77668dcede2149_sv.json&style=flat) | 2026-01-20 |
| 13 | [智能信息图](https://openwebui.com/posts/智能信息图_e04a48ff) | action | ![v](https://img.shields.io/badge/v-1.5.0-blue?style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_dl.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_vw.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_up.json&style=flat) | ![post_0c3f8621f77a9d5875d3c26ee38a3954_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0c3f8621f77a9d5875d3c26ee38a3954_sv.json&style=flat) | 2026-02-13 |
| 14 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | ![v](https://img.shields.io/badge/v-0.1.3-blue?style=flat) | ![post_68081377a06a5746efe798136a72c6b6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_dl.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_vw.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_up.json&style=flat) | ![post_68081377a06a5746efe798136a72c6b6_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_68081377a06a5746efe798136a72c6b6_sv.json&style=flat) | 2026-02-25 |
| 15 | [思维导图](https://openwebui.com/posts/智能生成交互式思维导图帮助用户可视化知识_8d4b097b) | action | ![v](https://img.shields.io/badge/v-0.9.2-blue?style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_dl.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_vw.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_up.json&style=flat) | ![post_c5bfbfd0d29694a04c597e26202b824f_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c5bfbfd0d29694a04c597e26202b824f_sv.json&style=flat) | 2026-02-13 |
| 16 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | ![v](https://img.shields.io/badge/v-1.2.2-blue?style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_dl.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_vw.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_up.json&style=flat) | ![post_fa447e583483020bc1bf35e74302c75c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_fa447e583483020bc1bf35e74302c75c_sv.json&style=flat) | 2026-02-13 |
| 17 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | ![v](https://img.shields.io/badge/v-0.2.4-blue?style=flat) | ![post_c68a2593e76ec324361358575b6501de_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_dl.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_vw.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_up.json&style=flat) | ![post_c68a2593e76ec324361358575b6501de_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_c68a2593e76ec324361358575b6501de_sv.json&style=flat) | 2026-02-13 |
| 18 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | ![v](https://img.shields.io/badge/v-1.0.0-blue?style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_dl.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_vw.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_up.json&style=flat) | ![post_14a3b01bc6559558b48a61a56dd3635d_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_14a3b01bc6559558b48a61a56dd3635d_sv.json&style=flat) | 2026-01-08 |
| 19 | [🚀 GitHub Copilot SDK Pipe v0.9.0: Copilot SDK Skills Core Capabilities & Extended Delivery](https://openwebui.com/posts/github_copilot_sdk_pipe_v090_copilot_sdk_skills_co_99a42452) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_dl.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_vw.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_up.json&style=flat) | ![post_0f2ccf8471a3db168298f4f1e86ba0f4_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_0f2ccf8471a3db168298f4f1e86ba0f4_sv.json&style=flat) | 2026-02-27 |
| 20 | [🚀 GitHub Copilot SDK Pipe v0.8.0: Conditional Tool Filtering & Publish Reliability 🎛️](https://openwebui.com/posts/github_copilot_sdk_pipe_v080_conditional_tool_filt_a5a3322d) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_dl.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_vw.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_up.json&style=flat) | ![post_7fdac7ddf86cc4cc7769319f237deff8_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_7fdac7ddf86cc4cc7769319f237deff8_sv.json&style=flat) | 2026-02-25 |
| 21 | [🚀 GitHub Copilot SDK Pipe v0.7.0: Native Tool UI & Zero-Config CLI 🛠️](https://openwebui.com/posts/github_copilot_sdk_pipe_v070_native_tool_ui_zero_c_4af38131) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_dl.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_vw.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_up.json&style=flat) | ![post_8aad0d77dbeaa0bdd3e6971274b5fa5c_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8aad0d77dbeaa0bdd3e6971274b5fa5c_sv.json&style=flat) | 2026-02-22 |
| 22 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_dl.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_vw.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_up.json&style=flat) | ![post_42a11f4f094a0fa757bfefece51b1180_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_42a11f4f094a0fa757bfefece51b1180_sv.json&style=flat) | 2026-02-10 |
| 23 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_858cb162732370288ce024b4f7944f69_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_dl.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_vw.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_up.json&style=flat) | ![post_858cb162732370288ce024b4f7944f69_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_858cb162732370288ce024b4f7944f69_sv.json&style=flat) | 2026-01-28 |
| 24 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | review | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_dl.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_vw.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_up.json&style=flat) | ![post_8db923aec1f58d282a2334db388aa5c2_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_8db923aec1f58d282a2334db388aa5c2_sv.json&style=flat) | 2026-01-14 |
| 25 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | post | ![v](https://img.shields.io/badge/v-N/A-gray?style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_dl.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_vw.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_up](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_up.json&style=flat) | ![post_e38b91e43262d29106345acfcd9dffba_sv](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_post_e38b91e43262d29106345acfcd9dffba_sv.json&style=flat) | 2026-01-10 |

View File

@@ -1,6 +1,6 @@
# Contributing Guide
Thank you for your interest in contributing to **OpenWebUI Extras**! We welcome contributions of plugins, prompts, documentation, and more.
Thank you for your interest in contributing to **OpenWebUI Extensions**! We welcome contributions of plugins, prompts, documentation, and more.
---
@@ -181,6 +181,6 @@ By contributing, you agree that your contributions will be licensed under the sa
## 🙏 Thank You!
Every contribution, no matter how small, helps make OpenWebUI Extras better for everyone. Thank you for being part of our community!
Every contribution, no matter how small, helps make OpenWebUI Extensions better for everyone. Thank you for being part of our community!
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/awesome-openwebui){ .md-button .md-button--primary }
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/openwebui-extensions){ .md-button .md-button--primary }

View File

@@ -1,6 +1,6 @@
# 贡献指南
感谢你对 **OpenWebUI Extras** 的兴趣!我们欢迎各种形式的贡献,包括插件、提示词、文档等。
感谢你对 **OpenWebUI Extensions** 的兴趣!我们欢迎各种形式的贡献,包括插件、提示词、文档等。
---
@@ -181,6 +181,6 @@ Update: 插件开发指南添加新示例
## 🙏 感谢
每一份贡献,无论大小,都有助于让 OpenWebUI Extras 变得更好。感谢你成为我们社区的一员!
每一份贡献,无论大小,都有助于让 OpenWebUI Extensions 变得更好。感谢你成为我们社区的一员!
[:fontawesome-brands-github: 在 GitHub 上查看](https://github.com/Fu-Jie/awesome-openwebui){ .md-button .md-button--primary }
[:fontawesome-brands-github: 在 GitHub 上查看](https://github.com/Fu-Jie/openwebui-extensions){ .md-button .md-button--primary }

View File

@@ -1,6 +1,6 @@
# 贡献指南
感谢你对 **OpenWebUI Extras** 的兴趣!我们欢迎各种形式的贡献,包括插件、提示词、文档等。
感谢你对 **OpenWebUI Extensions** 的兴趣!我们欢迎各种形式的贡献,包括插件、提示词、文档等。
---
@@ -181,6 +181,6 @@ Update: 插件开发指南添加新示例
## 🙏 感谢
每一份贡献,无论大小,都有助于让 OpenWebUI Extras 变得更好。感谢你成为我们社区的一员!
每一份贡献,无论大小,都有助于让 OpenWebUI Extensions 变得更好。感谢你成为我们社区的一员!
[:fontawesome-brands-github: 在 GitHub 上查看](https://github.com/Fu-Jie/awesome-openwebui){ .md-button .md-button--primary }
[:fontawesome-brands-github: 在 GitHub 上查看](https://github.com/Fu-Jie/openwebui-extensions){ .md-button .md-button--primary }

View File

@@ -0,0 +1,154 @@
# Copilot Engineering Configuration Plan
> This document defines production-grade engineering configuration for plugin development with GitHub Copilot, Gemini CLI, and antigravity development mode.
---
## 1. Goals
- Standardize plugin engineering workflow for AI-assisted development.
- Support dual assistant stack:
- GitHub Copilot (primary in-editor agent)
- Gemini CLI (secondary external execution/research lane)
- Introduce antigravity development mode for safer, reversible, high-velocity iteration.
---
## 2. Scope
This plan applies to:
- Plugin development (`actions`, `filters`, `pipes`, `pipelines`, `tools`)
- Documentation synchronization
- File generation/delivery workflow in OpenWebUI
- Streaming/tool-call rendering compatibility
---
## 3. Engineering Configuration (Copilot-centered)
### 3.1 Source of truth
- Primary standard file: `.github/copilot-instructions.md`
- Agent workflow file: `.agent/workflows/plugin-development.md`
- Runtime guidance docs:
- `docs/development/plugin-guide.md`
- `docs/development/plugin-guide.zh.md`
### 3.2 Required development contract
- Single-file i18n plugin source.
- Bilingual README (`README.md` + `README_CN.md`).
- Safe context extraction (`_get_user_context`, `_get_chat_context`).
- Structured event handling (`status`, `notification`, `execute`).
- No silent failures; logging + user-visible status.
### 3.3 Tool definition contract (Copilot SDK)
- Define tool params explicitly with `pydantic.BaseModel`.
- Use `params_type` in tool registration.
- Preserve defaults by avoiding forced null overrides.
- Keep tool names normalized and deterministic.
---
## 4. Gemini CLI Compatibility Profile
Gemini CLI is treated as a parallel capability channel, not a replacement.
### 4.1 Usage boundary
- Use for:
- rapid drafts
- secondary reasoning
- cross-checking migration plans
- Do not bypass repository conventions or plugin contracts.
### 4.2 Output normalization
All Gemini CLI outputs must be normalized before merge:
- Match repository style and naming rules.
- Preserve OpenWebUI plugin signatures and context methods.
- Convert speculative outputs into explicit, testable implementation points.
### 4.3 Conflict policy
When Copilot and Gemini suggestions differ:
1. Prefer repository standard compliance.
2. Prefer safer fallback behavior.
3. Prefer lower integration risk.
---
## 5. Antigravity Development Mode
Antigravity mode means high-speed delivery with strict reversibility.
### 5.1 Core principles
- Small, isolated edits
- Deterministic interfaces
- Multi-level fallback paths
- Roll-forward and rollback both feasible
### 5.2 Required patterns
- Timeout guards on frontend execution calls.
- Path sandbox validation for all workspace file operations.
- Dual-channel upload fallback (API first, local/DB fallback).
- Progressive status reporting for long-running tasks.
---
## 6. File Creation & Delivery Standard
### 6.1 Create files in controlled workspace
- Write artifacts in current workspace scope.
- Never use paths outside workspace boundary for deliverables.
### 6.2 Publish protocol
Use 3-step delivery:
1. local write
2. publish from workspace
3. present `/api/v1/files/{id}/content` link
### 6.3 Metadata policy
- Set `skip_rag=true` for generated downloadable artifacts where applicable.
- Keep filename generation deterministic (`chat_title -> markdown_title -> user+date`).
---
## 7. Plugin Development Norms for Multi-Agent Stack
- Compatible with GitHub Copilot and Gemini CLI under same coding contract.
- Keep streaming compatible with OpenWebUI native blocks (`<think>`, `<details type="tool_calls">`).
- Escape tool card attributes safely (`&quot;`) for parser stability.
- Preserve async non-blocking behavior.
---
## 8. Documentation Sync Rule
Any meaningful plugin engineering change must sync:
1. plugin code
2. plugin bilingual README
3. docs plugin detail pages (EN/ZH)
4. docs plugin indexes (EN/ZH)
5. root README update badge/date when release is prepared
---
## 9. Acceptance Checklist
- Copilot config and workflow references are valid.
- Gemini CLI outputs can be merged without violating conventions.
- Antigravity safety mechanisms are present.
- File creation and publication flow is reproducible.
- Streaming/tool-card output format remains OpenWebUI-compatible.

View File

@@ -0,0 +1,149 @@
# Copilot 工程化配置设计
> 本文档定义面向插件开发的工程化配置方案:支持 GitHub Copilot、兼容 Gemini CLI并引入“反重力开发”模式。
---
## 1. 目标
- 建立统一、可落地的 AI 协同开发标准。
- 支持双通道助手体系:
- GitHub Copilot编辑器内主通道
- Gemini CLI外部补充通道
- 在高迭代速度下保障可回滚、可审计、可发布。
---
## 2. 适用范围
适用于以下类型开发:
- 插件代码(`actions` / `filters` / `pipes` / `pipelines` / `tools`
- 文档同步与发布准备
- OpenWebUI 文件创建与交付流程
- 流式输出与工具卡片兼容性
---
## 3. Copilot 工程化主配置
### 3.1 规范来源
- 主规范:`.github/copilot-instructions.md`
- 工作流:`.agent/workflows/plugin-development.md`
- 运行时开发指南:
- `docs/development/plugin-guide.md`
- `docs/development/plugin-guide.zh.md`
### 3.2 强制开发契约
- 单文件 i18n 插件源码。
- README 双语(`README.md` + `README_CN.md`)。
- 上下文统一入口(`_get_user_context``_get_chat_context`)。
- 事件标准化(`status``notification``execute`)。
- 禁止静默失败(用户可见状态 + 后端日志)。
### 3.3 Copilot SDK 工具契约
- 参数必须 `pydantic.BaseModel` 显式定义。
- 工具注册必须声明 `params_type`
- 保留默认值语义,避免把未传参数强制覆盖为 `null`
- 工具名需可预测、可规范化。
---
## 4. Gemini CLI 兼容配置
Gemini CLI 作为补充通道,而不是替代主规范。
### 4.1 使用边界
- 适合:草案生成、方案对照、迁移校验。
- 不得绕过仓库规范与插件契约。
### 4.2 输出归一化
Gemini CLI 输出合入前必须完成:
- 命名与结构对齐仓库约束。
- 保留 OpenWebUI 插件标准签名与上下文方法。
- 将“建议性文字”转换为可执行、可验证实现点。
### 4.3 冲突决策
Copilot 与 Gemini 建议冲突时按优先级处理:
1. 规范一致性优先
2. 安全回退优先
3. 低集成风险优先
---
## 5. 反重力开发Antigravity模式
反重力开发 = 高速迭代 + 强回退能力。
### 5.1 核心原则
- 小步、隔离、可逆变更
- 接口稳定、行为可预测
- 多级回退链路
- 支持前滚与回滚
### 5.2 强制模式
- 前端执行调用必须设置超时保护。
- 工作区文件操作必须做路径沙箱校验。
- 上传链路采用 API 优先 + 本地/DB 回退。
- 长任务必须分阶段状态反馈。
---
## 6. 文件创建与交付标准
### 6.1 创建范围
- 交付文件仅在受控 workspace 内创建。
- 禁止将交付产物写到 workspace 边界之外。
### 6.2 三步交付协议
1. 本地写入
2. 从 workspace 发布
3. 返回并展示 `/api/v1/files/{id}/content`
### 6.3 元数据策略
- 需要绕过检索时为产物标记 `skip_rag=true`
- 文件名采用确定性策略:`chat_title -> markdown_title -> user+date`
---
## 7. 多助手并行下的插件开发规范
- 在统一契约下同时兼容 GitHub Copilot 与 Gemini CLI。
- 流式输出保持 OpenWebUI 原生兼容(`<think>``<details type="tool_calls">`)。
- 工具卡片属性严格转义(`&quot;`)保证解析稳定。
- 全链路保持异步非阻塞。
---
## 8. 文档同步规则
插件工程化变更发生时,至少同步:
1. 插件代码
2. 插件双语 README
3. docs 详情页EN/ZH
4. docs 索引页EN/ZH
5. 发布准备阶段同步根 README 日期徽章
---
## 9. 验收清单
- Copilot 配置与工作流引用有效。
- Gemini CLI 输出可无缝合入且不破坏规范。
- 反重力安全机制完整。
- 文件创建/发布流程可复现。
- 流式与工具卡片格式保持 OpenWebUI 兼容。

View File

@@ -0,0 +1,126 @@
# GitHub Copilot SDK Tool Filtering Logic Documentation
## Overview
The tool filtering logic ensures that changes made in the **OpenWebUI admin panel take effect on the very next chat message** — no restart or cache flush required. The design balances three goals: administrator control, user autonomy, and built-in feature availability.
## Priority Hierarchy
Filtering is applied top-to-bottom. A higher layer can fully block a lower one:
| Priority | Layer | Controls |
|---|---|---|
| 1 (Highest) | **Plugin Valve toggles** | `ENABLE_OPENWEBUI_TOOLS`, `ENABLE_MCP_SERVER`, `ENABLE_OPENAPI_SERVER` — category master switches |
| 2 | **Admin backend server toggle** | Per-server `config.enable` in OpenWebUI Connections panel — blocks specific servers |
| 3 (Lowest) | **User Chat menu selection** | `tool_ids` from the chat UI — selects which enabled items to use |
---
## Core Decision Logic (Flowchart)
```mermaid
graph TD
A[New message arrives] --> V{Plugin Valve enabled\nfor this category?}
V -- No --> VX[Drop all tools in this category]
V -- Yes --> B{Admin backend:\nconfig.enable = True?}
B -- No --> C[Skip this server]
B -- Yes --> F{Built-in or Custom/Server tool?}
F -- Built-in --> G{Any builtin: IDs\nselected in Chat?}
G -- Yes --> H[Enable ONLY the mapped categories\nunselected categories set to False]
G -- No --> I[Enable default 4 categories:\nweb_search, image_generation,\ncode_interpreter, memory]
F -- Custom / Server --> J{Any custom IDs\nselected in Chat?}
J -- Yes --> K[Load ONLY the selected IDs]
J -- No --> L[Load ALL admin-enabled custom tools]
H & I & K & L --> M[Always inject: publish_file_from_workspace]
M --> N[Start / Resume Copilot SDK Session]
```
---
## Scenario Reference Table
| User selects in Chat | Custom tools loaded | Built-in tools loaded |
|---|---|---|
| Nothing | All admin-enabled | Default 4 (search, image, code, memory) |
| Only `builtin:xxx` | All admin-enabled (unaffected) | Only selected categories |
| Only custom/server IDs | Only selected IDs | Default 4 |
| Both builtin and custom | Only selected custom IDs | Only selected builtin categories |
---
## Technical Implementation Details
### 1. Real-time Admin Sync (No Caching)
Every request re-reads `TOOL_SERVER_CONNECTIONS.value` live. There is **no in-memory cache** for server state. As a result:
- Enable a server in the admin panel → it appears on the **next message**.
- Disable a server → it is dropped on the **next message**.
```python
# Read live on every request — no cache
if hasattr(TOOL_SERVER_CONNECTIONS, "value"):
raw_connections = TOOL_SERVER_CONNECTIONS.value
for server in connections:
is_enabled = config.get("enable", False) # checked per-server, per-request
if not is_enabled:
continue # skipped immediately — hard block
```
### 2. Built-in Tool Category Mapping
The plugin maps individual `builtin:func_name` IDs to one of 9 categories understood by `get_builtin_tools`. When the user selects specific builtins, **only those categories are enabled; unselected categories are explicitly set to `False`** (not omitted) to prevent OpenWebUI's default-`True` fallback:
```python
if builtin_selected:
# Strict mode: set every category explicitly
for cat in all_builtin_categories: # all 9
is_enabled = cat in enabled_categories # only selected ones are True
builtin_tools_meta[cat] = is_enabled # unselected are explicitly False
else:
# Default mode: only the 4 core categories
default_builtin_categories = [
"web_search", "image_generation", "code_interpreter", "memory"
]
for cat in all_builtin_categories:
builtin_tools_meta[cat] = cat in default_builtin_categories
features.update(req_features) # merge backend feature flags
```
### 3. Custom Tool "Select-All" Fallback
The whitelist is activated **only when the user explicitly selects custom/server IDs**. Selecting only `builtin:` IDs does not trigger the custom whitelist, so all admin-enabled servers remain accessible:
```python
# custom_selected contains only non-builtin: IDs
if custom_selected:
# Whitelist active: keep only what the user picked
tool_ids = [tid for tid in available_ids if tid in custom_selected]
else:
# No custom selection: load everything enabled in backend
tool_ids = available_ids
```
The same rule applies to MCP servers in `_parse_mcp_servers`.
### 4. Admin Backend Strict Validation
Applied uniformly to both OpenAPI and MCP servers, handling both dict and Pydantic object shapes:
```python
is_enabled = False
config = server.get("config", {}) if isinstance(server, dict) else getattr(server, "config", {})
is_enabled = config.get("enable", False) if isinstance(config, dict) else getattr(config, "enable", False)
if not is_enabled:
continue # hard skip — no user or valve setting can override this
```
## Important Notes
- **SDK Internal Tools**: `available_tools = None` is passed to the session so SDK-native capabilities (`read_file`, `shell`, etc.) are never accidentally blocked by the custom tool list.
- **Persistent Tool**: `publish_file_from_workspace` is always injected after all filtering — it is required for the file delivery workflow regardless of any toggle.

View File

@@ -0,0 +1,206 @@
# GitHub Copilot SDK 工具过滤逻辑开发文档
## 核心需求
**管理员在后台修改工具服务的启用状态后,用户发送下一条消息时立即生效,无需重启服务或刷新缓存。**
过滤逻辑同时兼顾两个目标:管理员管控权、用户自主选择权。内置工具则完全独立,仅由模型配置决定。
---
## 工具分类说明
本文档涉及两类完全独立的工具,权限控制机制不同:
| 工具类型 | 说明 | 权限控制来源 |
|---|---|---|
| **内置工具Builtin Tools** | OpenWebUI 原生能力:时间、知识库、记忆、联网搜索、图像生成、代码解释器等 | 仅由模型配置 `meta.builtinTools` 决定,**与 Chat 前端选择无关** |
| **OpenWebUI Tools** | 用户安装的 Python 工具插件 | 插件 Valve + Chat 工具选择tool_ids |
| **工具服务器OpenAPI / MCP** | 外部 OpenAPI Server、MCP Server | 插件 Valve + 管理员 `config.enable` + `function_name_filter_list` + Chat 工具选择tool_ids |
---
## 内置工具权限控制(模型配置驱动,与前端无关)
内置工具**完全由模型配置决定**Chat 界面的工具选择对其没有任何影响。
### 模型 `meta.builtinTools` 字段
在模型(自定义模型或基础模型)的 `meta` 字段中有一个可选的 `builtinTools` 对象:
```json
{
"meta": {
"capabilities": { "builtin_tools": true },
"builtinTools": {
"time": false,
"memory": true,
"chats": true,
"notes": true,
"knowledge": true,
"channels": true,
"web_search": true,
"image_generation": true,
"code_interpreter": true
}
}
}
```
**判定规则(源码 `utils/tools.py`**
```python
def is_builtin_tool_enabled(category: str) -> bool:
builtin_tools = model.get("info", {}).get("meta", {}).get("builtinTools", {})
return builtin_tools.get(category, True) # 缺省时默认 True
```
- `builtinTools` 字段**不存在** → 所有内置工具类别默认全部开启
- `builtinTools` 字段**存在** → 仅值为 `true` 的类别开启,其余关闭
---
## OpenWebUI Tools 和工具服务器的优先级层级
这两类工具的过滤从上到下依次执行,**受 Chat 前端选择影响**
| 优先级 | 层级 | 控制范围 |
|---|---|---|
| 1最高 | **插件 Valve 开关** | `ENABLE_OPENWEBUI_TOOLS` / `ENABLE_MCP_SERVER` / `ENABLE_OPENAPI_SERVER` — 类别总开关 |
| 2 | **管理员后端服务器开关** | OpenWebUI 连接面板中每个服务器的 `config.enable` — 控制具体服务器是否启用 |
| 3 | **管理员函数名过滤列表** | 工具服务器 `config.function_name_filter_list` — 限制该服务器对外暴露的函数列表(逗号分隔) |
| 4最低 | **用户 Chat 工具选择** | Chat 界面的 `tool_ids` — 在已启用范围内进一步筛选:未选则全选,有选则仅选中的 |
### 管理员函数名过滤列表说明
OpenWebUI 后台的工具服务器连接配置中支持设置 `function_name_filter_list` 字段(逗号分隔的函数名),用于限制该服务器对外暴露的函数。源码逻辑:
```python
# utils/tools.py
function_name_filter_list = tool_server_connection.get("config", {}).get("function_name_filter_list", "")
if isinstance(function_name_filter_list, str):
function_name_filter_list = function_name_filter_list.split(",")
for spec in specs:
function_name = spec["name"]
if function_name_filter_list:
if not is_string_allowed(function_name, function_name_filter_list):
continue # 不在列表中的函数被跳过
```
- 列表**为空** → 该服务器所有函数均可用
- 列表**有值** → 只有名称匹配的函数会被暴露给用户
---
## 核心判定流程
```mermaid
graph TD
A[新消息到来] --> BT[内置工具:读模型 meta.builtinTools]
BT --> BT2{builtinTools 字段存在?}
BT2 -- 否 --> BT3[开启全部内置工具]
BT2 -- 是 --> BT4[仅开启值为 true 的类别]
A --> CT[OpenWebUI Tools / 工具服务器]
CT --> V{插件 Valve 开启了该类别?}
V -- 否 --> VX[丢弃该类别]
V -- 是 --> B{后端 config.enable = True?}
B -- 否 --> C[跳过该服务器]
B -- 是 --> FL{function_name_filter_list 有值?}
FL -- 是 --> FL2[过滤掉不在列表中的函数]
FL -- 否 --> J
FL2 --> J{Chat tool_ids 有勾选?}
J -- 有 --> K[仅加载勾选的 ID]
J -- 无 --> L[加载所有后台已启用工具]
BT3 & BT4 & K & L --> M[始终注入: publish_file_from_workspace]
M --> N[启动/恢复 Copilot SDK 会话]
```
---
## 场景速查表
### 内置工具(与前端选择无关)
| 模型配置 | 结果 |
|---|---|
| `meta.builtinTools` 字段不存在 | 全部内置工具类别开启 |
| `meta.builtinTools` 字段存在 | 仅 `true` 的类别开启 |
### OpenWebUI Tools / 工具服务器(受 Chat 前端选择影响)
| Chat 工具选择情况 | 加载逻辑 |
|---|---|
| 什么都没选 | 加载所有 Valve 开启且后台已启用的工具Python Tools + OpenAPI + MCP |
| 选了部分 tool_ids | 仅加载勾选的 ID必须同时通过 Valve 和 config.enable 校验) |
---
## 代码实现详述
### 1. 管理员后台变更即时同步
OpenWebUI 通过 `PersistentConfig` + Redis 保证多 worker 之间的配置同步,插件直接读取 `request.app.state.config.TOOL_SERVER_CONNECTIONS` 即可获取最新值:
- 后台**启用**一个服务器 → **下一条消息**就出现。
- 后台**禁用**一个服务器 → **下一条消息**就消失。
```python
# 直接读取 OpenWebUI 的配置对象,有 Redis 时每次读取都会同步最新值
connections = request.app.state.config.TOOL_SERVER_CONNECTIONS # list
for server in connections:
config = server.get("config", {})
is_enabled = config.get("enable", False) # 每条服务器、每次请求都检查
if not is_enabled:
continue # 立即跳过,硬性拦截
```
### 2. 内置工具直接透传给 OpenWebUI 处理
插件调用 OpenWebUI 的 `get_builtin_tools(request, extra_params, model)` 时,将 `model` 原样传入即可。OpenWebUI 内部会自动读取 `model.info.meta.builtinTools` 来决定哪些内置工具生效:
```python
# OpenWebUI 源码 utils/tools.py 中的判定逻辑(开发参考,非插件代码)
def is_builtin_tool_enabled(category: str) -> bool:
builtin_tools = model.get("info", {}).get("meta", {}).get("builtinTools", {})
return builtin_tools.get(category, True) # 缺省值 True未配置时全部开启
```
插件无需自行维护内置工具分类映射,也不需要向 `builtinTools` 注入任何值。
### 3. 自定义工具"默认全选"(白名单仅在显式勾选时激活)
白名单**只有在用户明确勾选了 tool_ids 时才启用**。未勾选任何工具时,加载所有后台已启用工具:
```python
# tool_ids 来自 Chat 请求体
if tool_ids:
# 白名单模式:严格只保留勾选项
available_ids = [tid for tid in available_ids if tid in tool_ids]
else:
# 无勾选:加载所有后台已启用工具(免配置可用)
pass # available_ids 保持不变
```
MCP 服务器的 `_parse_mcp_servers` 遵循同样规则。
### 4. 后端状态硬校验OpenAPI 和 MCP 统一处理)
```python
is_enabled = False
config = server.get("config", {}) if isinstance(server, dict) else getattr(server, "config", {})
is_enabled = config.get("enable", False) if isinstance(config, dict) else getattr(config, "enable", False)
if not is_enabled:
continue # 硬性跳过,任何用户或 Valve 设置都无法绕过
```
---
## 注意事项
- **SDK 内部工具**:向会话传 `available_tools = None`,保证 `read_file``shell` 等 SDK 原生能力不被自定义工具列表意外屏蔽。
- **始终注入的工具**`publish_file_from_workspace` 在所有过滤完成后硬性追加,是文件交付工作流的必要依赖,不受任何开关影响。

View File

@@ -1,6 +1,6 @@
# Documentation Writing Guide
This guide explains how to write and contribute documentation for OpenWebUI Extras.
This guide explains how to write and contribute documentation for OpenWebUI Extensions.
---
@@ -21,8 +21,8 @@ Our documentation is built with [MkDocs](https://www.mkdocs.org/) and the [Mater
```bash
# Clone the repository
git clone https://github.com/Fu-Jie/awesome-openwebui.git
cd awesome-openwebui
git clone https://github.com/Fu-Jie/openwebui-extensions.git
cd openwebui-extensions
# Install dependencies
pip install -r requirements.txt
@@ -122,7 +122,7 @@ Step-by-step usage instructions.
## Source Code
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/awesome-openwebui/tree/main/plugins/...){ .md-button }
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins/...){ .md-button }
```
---

View File

@@ -1,6 +1,6 @@
# 文档编写指南
本文介绍如何为 OpenWebUI Extras 编写与贡献文档。
本文介绍如何为 OpenWebUI Extensions 编写与贡献文档。
---
@@ -21,8 +21,8 @@
```bash
# 克隆仓库
git clone https://github.com/Fu-Jie/awesome-openwebui.git
cd awesome-openwebui
git clone https://github.com/Fu-Jie/openwebui-extensions.git
cd openwebui-extensions
# 安装依赖
pip install -r requirements.txt
@@ -122,7 +122,7 @@ Step-by-step usage instructions.
## Source Code
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/awesome-openwebui/tree/main/plugins/...){ .md-button }
[:fontawesome-brands-github: View on GitHub](https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins/...){ .md-button }
```
---

View File

@@ -1,6 +1,6 @@
# Development
Learn how to develop plugins and contribute to OpenWebUI Extras.
Learn how to develop plugins and contribute to OpenWebUI Extensions.
---
@@ -24,6 +24,14 @@ Learn how to develop plugins and contribute to OpenWebUI Extras.
[:octicons-arrow-right-24: Read the Guide](documentation-guide.md)
- :material-robot:{ .lg .middle } **Copilot Engineering Plan**
---
Engineering configuration for GitHub Copilot + Gemini CLI + antigravity development mode.
[:octicons-arrow-right-24: Read the Plan](copilot-engineering-plan.md)
- :material-github:{ .lg .middle } **Contributing**
---
@@ -164,5 +172,6 @@ user_language = __user__.get("language", "en-US")
## Resources
- [Full Development Guide](plugin-guide.md)
- [Plugin Examples](https://github.com/Fu-Jie/awesome-openwebui/tree/main/plugins)
- [Copilot Engineering Plan](copilot-engineering-plan.md)
- [Plugin Examples](https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins)
- [OpenWebUI Documentation](https://docs.openwebui.com/)

View File

@@ -1,6 +1,6 @@
# 开发指南
了解如何开发插件并为 OpenWebUI Extras 做出贡献。
了解如何开发插件并为 OpenWebUI Extensions 做出贡献。
---
@@ -24,6 +24,14 @@
[:octicons-arrow-right-24: 阅读指南](documentation-guide.md)
- :material-robot:{ .lg .middle } **Copilot 工程化配置**
---
面向 GitHub Copilot + Gemini CLI + 反重力开发模式的工程化设计文档。
[:octicons-arrow-right-24: 阅读文档](copilot-engineering-plan.md)
- :material-github:{ .lg .middle } **贡献指南**
---
@@ -164,5 +172,6 @@ user_language = __user__.get("language", "en-US")
## 资源
- [完整开发指南](plugin-guide.md)
- [插件示例](https://github.com/Fu-Jie/awesome-openwebui/tree/main/plugins)
- [Copilot 工程化配置](copilot-engineering-plan.md)
- [插件示例](https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins)
- [OpenWebUI 文档](https://docs.openwebui.com/)

View File

@@ -7,11 +7,13 @@
## 📚 Table of Contents
1. [Quick Start](#1-quick-start)
2. [Core Concepts & SDK Details](#2-core-concepts-sdk-details)
3. [Deep Dive into Plugin Types](#3-deep-dive-into-plugin-types)
4. [Advanced Development Patterns](#4-advanced-development-patterns)
5. [Best Practices & Design Principles](#5-best-practices-design-principles)
6. [Troubleshooting](#6-troubleshooting)
2. [Project Structure & Naming](#2-project-structure--naming)
3. [Core Concepts & SDK Details](#3-core-concepts--sdk-details)
4. [Deep Dive into Plugin Types](#4-deep-dive-into-plugin-types)
5. [Advanced Development Patterns](#5-advanced-development-patterns)
6. [Best Practices & Design Principles](#6-best-practices--design-principles)
7. [Workflow & Process](#7-workflow--process)
8. [Troubleshooting](#8-troubleshooting)
---
@@ -64,9 +66,39 @@ class Action:
---
## 2. Core Concepts & SDK Details
## 2. Project Structure & Naming
### 2.1 ⚠️ Important: Sync vs Async
### 2.1 Language & Code Requirements
- **Single Code File**: `plugins/{type}/{name}/{name}.py`. Never create separate source files for different languages.
- **Built-in i18n**: Must dynamically switch UI, prompts, and logs based on user language.
- **Documentation**: Must include both `README.md` (English) and `README_CN.md` (Chinese).
### 2.2 Docstring Standard
Each plugin file must start with a standardized docstring:
```python
"""
title: Plugin Name
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
version: 0.1.0
icon_url: data:image/svg+xml;base64,<base64-encoded-svg>
requirements: dependency1==1.0.0, dependency2>=2.0.0
description: Brief description of plugin functionality.
"""
```
- **icon_url**: Required for Action plugins. Must be Base64 encoded SVG from [Lucide Icons](https://lucide.dev/icons/).
- **requirements**: Only list dependencies not installed in the OpenWebUI environment.
---
## 3. Core Concepts & SDK Details
### 3.1 ⚠️ Important: Sync vs Async
OpenWebUI plugins run within an `asyncio` event loop.
@@ -75,7 +107,7 @@ OpenWebUI plugins run within an `asyncio` event loop.
- **Pitfall**: Calling synchronous methods directly (e.g., `time.sleep`, `requests.get`) will freeze the entire server
- **Solution**: Wrap synchronous calls using `await asyncio.to_thread(sync_func, ...)`
### 2.2 Core Parameters
### 3.2 Core Parameters
All plugin methods (`inlet`, `outlet`, `pipe`, `action`) support injecting the following special parameters:
@@ -88,30 +120,43 @@ All plugin methods (`inlet`, `outlet`, `pipe`, `action`) support injecting the f
| `__event_emitter__` | `func` | **One-way Notification**. Used to send Toast notifications or status bar updates |
| `__event_call__` | `func` | **Two-way Interaction**. Used to execute JS code, show confirmation dialogs, or input boxes |
### 2.3 Configuration System (Valves)
### 3.3 Configuration System (Valves)
- **`Valves`**: Global admin configuration
- **`UserValves`**: User-level configuration (higher priority, overrides global)
Use Pydantic BaseModel to define configurable parameters. All Valves fields must use **UPPER_SNAKE_CASE**.
```python
class Filter:
from pydantic import BaseModel, Field
class Action:
class Valves(BaseModel):
API_KEY: str = Field(default="", description="Global API Key")
class UserValves(BaseModel):
API_KEY: str = Field(default="", description="User Private API Key")
def inlet(self, body, __user__):
# Prioritize user's Key
user_valves = __user__.get("valves", self.UserValves())
api_key = user_valves.API_KEY or self.valves.API_KEY
SHOW_STATUS: bool = Field(default=True, description="Whether to show operation status updates.")
# ...
```
### 3.4 Context Access
All plugins **must** use `_get_user_context` and `_get_chat_context` methods to safely extract information, rather than accessing `__user__` or `body` directly.
### 3.5 Event Emission & Logging
- **Event Emission**: Implement helper methods `_emit_status` and `_emit_notification`.
- **Frontend Console Debugging**: Highly recommended for real-time data flow viewing. Use `_emit_debug_log` to print structured debug logs in the browser console.
- **Server-side Logging**: Use Python's standard `logging` module. Do not use `print()`.
### 3.6 Database & File Storage
- **Database**: Re-use Open WebUI's internal database connection (`open_webui.internal.db`).
- **File Storage**: Implement multi-level fallback mechanisms (DB -> S3 -> Local -> URL -> API) to ensure compatibility across all storage configurations.
### 3.7 Internationalization (i18n)
Define a `TRANSLATIONS` dictionary and use a robust language detection mechanism (Multi-level Fallback: JS localStorage -> HTTP Accept-Language -> User Profile -> en-US).
---
## 3. Deep Dive into Plugin Types
## 4. Deep Dive into Plugin Types
### 3.1 Action
### 4.1 Action
**Role**: Adds buttons below messages that trigger upon user click.
@@ -136,7 +181,7 @@ async def action(self, body, __event_call__):
await __event_call__({"type": "execute", "data": {"code": js}})
```
### 3.2 Filter
### 4.2 Filter
**Role**: Middleware that intercepts and modifies requests/responses.
@@ -157,7 +202,7 @@ async def inlet(self, body, __metadata__):
return body
```
### 3.3 Pipe
### 4.3 Pipe
**Role**: Custom Model/Agent.
@@ -182,18 +227,27 @@ class Pipe:
return r.iter_lines()
```
### 4.4 Copilot SDK Tool Definition Standards
When developing custom tools for GitHub Copilot SDK, you **must** define a Pydantic `BaseModel` for parameters and explicitly reference it using `params_type` in `define_tool`.
### 4.5 Copilot SDK Streaming & Tool Card Standards
- **Reasoning Streaming**: Must use native `<think>` tags and ensure proper closure (`\n</think>\n`) before outputting main content or tool calls.
- **Native Tool Calls Block**: Output strictly formatted HTML `<details type="tool_calls"...>` blocks. Ensure all double quotes in attributes are escaped as `&quot;`.
---
## 4. Advanced Development Patterns
## 5. Advanced Development Patterns
### 4.1 Pipe & Filter Collaboration
### 5.1 Pipe & Filter Collaboration
Use `__request__.app.state` to share data between plugins:
- **Pipe**: `__request__.app.state.search_results = [...]`
- **Filter (Outlet)**: Read `search_results` and format them as citation links
### 4.2 Async Background Tasks
### 5.2 Async Background Tasks
Execute time-consuming operations without blocking the user response:
@@ -209,7 +263,7 @@ async def background_job(self, chat_id):
pass
```
### 4.3 Calling Built-in LLM
### 5.3 Calling Built-in LLM
```python
from open_webui.utils.chat import generate_chat_completion
@@ -235,13 +289,13 @@ llm_response = await generate_chat_completion(
)
```
### 4.4 JS Render to Markdown (Data URL Embedding)
### 5.4 JS Render to Markdown (Data URL Embedding)
For scenarios requiring complex frontend rendering (e.g., AntV charts, Mermaid diagrams) but wanting **persistent pure Markdown output**, use the Data URL embedding pattern:
#### Workflow
```
```text
┌──────────────────────────────────────────────────────────────┐
│ 1. Python Action │
│ ├── Analyze message content │
@@ -259,116 +313,28 @@ For scenarios requiring complex frontend rendering (e.g., AntV charts, Mermaid d
└──────────────────────────────────────────────────────────────┘
```
#### Python Side (Send JS for Execution)
### 5.5 Agent File Delivery Standards (3-Step Delivery Protocol)
```python
async def action(self, body, __event_call__, __metadata__, ...):
chat_id = self._extract_chat_id(body, __metadata__)
message_id = self._extract_message_id(body, __metadata__)
# Generate JS code
js_code = self._generate_js_code(
chat_id=chat_id,
message_id=message_id,
data=processed_data,
)
# Execute JS
if __event_call__:
await __event_call__({
"type": "execute",
"data": {"code": js_code}
})
```
#### JavaScript Side (Render and Write-back)
```javascript
(async function() {
// 1. Load visualization library
if (typeof VisualizationLib === 'undefined') {
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://cdn.example.com/lib.min.js';
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// 2. Create offscreen container
const container = document.createElement('div');
container.style.cssText = 'position:absolute;left:-9999px;';
document.body.appendChild(container);
// 3. Render visualization
const instance = new VisualizationLib({ container });
instance.render(data);
// 4. Export to Data URL
const dataUrl = await instance.toDataURL({ type: 'svg', embedResources: true });
// 5. Cleanup
instance.destroy();
document.body.removeChild(container);
// 6. Generate Markdown image
const markdownImage = `![Chart](${dataUrl})`;
// 7. Update message via API
const token = localStorage.getItem("token");
await fetch(`/api/v1/chats/${chatId}/messages/${messageId}/event`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({
type: "chat:message",
data: { content: originalContent + "\n\n" + markdownImage }
})
});
})();
```
#### Benefits
- **Pure Markdown Output**: Standard Markdown image syntax, no HTML code blocks
- **Self-Contained**: Images embedded as Base64 Data URL, no external dependencies
- **Persistent**: Via API write-back, images remain after page reload
- **Cross-Platform**: Works on any client supporting Markdown images
#### HTML Injection vs JS Render to Markdown
| Feature | HTML Injection | JS Render + Markdown |
|---------|----------------|----------------------|
| Output Format | HTML code block | Markdown image |
| Interactivity | ✅ Buttons, animations | ❌ Static image |
| External Deps | Requires JS libraries | None (self-contained) |
| Persistence | Depends on browser | ✅ Permanent |
| File Export | Needs special handling | ✅ Direct export |
| Use Case | Interactive content | Infographics, chart snapshots |
#### Reference Implementations
- `plugins/actions/infographic/infographic.py` - Production-ready implementation using AntV + Data URL
1. **Write Local**: Create files in the current execution directory (`.`).
2. **Publish**: Call `publish_file_from_workspace(filename='name.ext')`.
3. **Display Link**: Present the returned `download_url` as a Markdown link.
---
## 5. Best Practices & Design Principles
## 6. Best Practices & Design Principles
### 5.1 Naming & Positioning
### 6.1 Naming & Positioning
- **Short & Punchy**: e.g., "FlashCard", "DeepRead". Avoid generic terms like "Text Analysis Assistant"
- **Complementary**: Don't reinvent the wheel; clarify what specific problem your plugin solves
### 5.2 User Experience (UX)
### 6.2 User Experience (UX)
- **Timely Feedback**: Send a `notification` ("Generating...") before time-consuming operations
- **Visual Appeal**: When Action outputs HTML, use modern CSS (rounded corners, shadows, gradients)
- **Smart Guidance**: If text is too short, prompt the user: "Suggest entering more content for better results"
### 5.3 Error Handling
### 6.3 Error Handling
!!! danger "Never fail silently"
Always catch exceptions and inform the user via `__event_emitter__`.
@@ -384,9 +350,39 @@ except Exception as e:
})
```
### 6.4 Long-running Task Notifications
If a foreground task is expected to take more than 3 seconds, implement a user notification mechanism (e.g., sending a notification every 5 seconds).
---
## 6. Troubleshooting
## 7. Workflow & Process
### 7.1 Source-derived Knowledge (from `plugins/`)
- **Input/context safety**: normalize multimodal text extraction, use `_get_user_context` / `_get_chat_context`, and protect frontend language detection with timeout guards.
- **Long task UX**: emit immediate `status/notification`, then staged progress updates; keep full exception detail in backend logs.
- **HTML merge strategy**: use stable wrapper markers (`OPENWEBUI_PLUGIN_OUTPUT`) and support both overwrite and merge modes.
- **Theme consistency**: detect parent/system theme and apply theme-aware rendering/export styles for iframe-based outputs.
- **Render-export-persist loop**: offscreen render (SVG/PNG) -> upload `/api/v1/files/` -> event update + persistence update to avoid refresh loss.
- **DOCX production path**: `TITLE_SOURCE` fallback naming, reasoning-block stripping, native Word math (`latex2mathml + mathml2omml`), and citation/reference anchoring.
- **File retrieval fallback chain**: DB inline -> S3 direct -> local path variants -> public URL -> internal API -> raw fields, with max-byte guards on each stage.
- **Filter singleton discipline**: do not store request-scoped mutable state on `self`; compute from request context each run.
- **Async compression pattern**: `inlet` summary injection + `outlet` background summary generation, with model-threshold override and system-message protection.
- **Workspace/tool hardening**: explicit `params_type` schemas, strict path-boundary validation, and publish flow returning `/api/v1/files/{id}/content` with `skip_rag=true` metadata.
- **MoE refinement pipeline**: detect aggregation prompts, parse segmented responses, and rewrite to synthesis-oriented master prompt with optional reroute model.
### 7.2 Copilot Engineering Configuration
- For repository-wide AI-assisted engineering setup (GitHub Copilot + Gemini CLI + antigravity mode), follow `docs/development/copilot-engineering-plan.md`.
- This plan defines the shared contract for tool parameter schema/routing, file creation/publish protocol, rollback-safe delivery patterns, and streaming/tool-card compatibility.
- **Consistency Maintenance**: Any addition, modification, or removal of a plugin must simultaneously update the plugin code, READMEs, project docs, doc indexes, and the root README.
- **Release Workflow**: Pushing to `main` triggers automatic release. Ensure version numbers are updated and follow SemVer. Use Conventional Commits.
---
## 8. Troubleshooting
??? question "HTML not showing?"
Ensure it's wrapped in a ` ```html ... ``` ` code block.
@@ -406,6 +402,6 @@ except Exception as e:
## Additional Resources
- [:fontawesome-brands-github: Plugin Examples](https://github.com/Fu-Jie/awesome-openwebui/tree/main/plugins)
- [:fontawesome-brands-github: Plugin Examples](https://github.com/Fu-Jie/openwebui-extensions/tree/main/plugins)
- [:material-book-open-variant: OpenWebUI Official Docs](https://docs.openwebui.com/)
- [:material-forum: Community Discussions](https://github.com/open-webui/open-webui/discussions)

View File

@@ -4,15 +4,16 @@
## 📚 目录
1. [插件开发快速入门](#1-quick-start)
2. [核心概念与 SDK 详解](#2-core-concepts-sdk-details)
3. [插件类型深度解析](#3-plugin-types)
* [Action (动作)](#31-action)
* [Filter (过滤器)](#32-filter)
* [Pipe (管道)](#33-pipe)
4. [高级开发模式](#4-advanced-patterns)
5. [最佳实践与设计原则](#5-best-practices)
6. [故障排查](#6-troubleshooting)
1. [插件开发快速入门](#1-quick-start)
2. [核心概念与 SDK 详解](#2-core-concepts-sdk-details)
3. [插件类型深度解析](#3-plugin-types)
* [Action (动作)](#31-action)
* [Filter (过滤器)](#32-filter)
* [Pipe (管道)](#33-pipe)
4. [高级开发模式](#4-advanced-patterns)
5. [最佳实践与设计原则](#5-best-practices)
6. [仓库规范openwebui-extensions](#6-repo-standards)
7. [故障排查](#7-troubleshooting)
---
@@ -21,9 +22,10 @@
### 1.1 什么是 OpenWebUI 插件?
OpenWebUI 插件(官方称为 "Functions")是扩展平台功能的主要方式。它们运行在后端 Python 环境中,允许你:
* 🔌 **集成新模型**:通过 Pipe 接入 Claude、Gemini 或自定义 RAG。
* 🎨 **增强交互**:通过 Action 在消息旁添加按钮(如"导出"、"生成图表"
* 🔧 **干预流程**:通过 Filter 在请求前后修改数据(如注入上下文、敏感词过滤)。
* 🔌 **集成新模型**:通过 Pipe 接入 Claude、Gemini 或自定义 RAG
* 🎨 **增强交互**:通过 Action 在消息旁添加按钮(如"导出"、"生成图表")。
* 🔧 **干预流程**:通过 Filter 在请求前后修改数据(如注入上下文、敏感词过滤)。
### 1.2 你的第一个插件 (Hello World)
@@ -69,9 +71,10 @@ class Action:
### 2.1 ⚠️ 重要:同步与异步
OpenWebUI 插件运行在 `asyncio` 事件循环中。
* **原则**:所有 I/O 操作(数据库、文件、网络)必须非阻塞。
* **陷阱**:直接调用同步方法(如 `time.sleep`, `requests.get`)会卡死整个服务器
* **解决**:使用 `await asyncio.to_thread(sync_func, ...)` 包装同步调用
* **原则**:所有 I/O 操作(数据库、文件、网络)必须非阻塞
* **陷阱**:直接调用同步方法(如 `time.sleep`, `requests.get`)会卡死整个服务器
* **解决**:使用 `await asyncio.to_thread(sync_func, ...)` 包装同步调用。
### 2.2 核心参数详解
@@ -88,8 +91,8 @@ OpenWebUI 插件运行在 `asyncio` 事件循环中。
### 2.3 配置系统 (Valves)
* **`Valves`**: 管理员全局配置。
* **`UserValves`**: 用户级配置(优先级更高,可覆盖全局)。
* **`Valves`**: 管理员全局配置。
* **`UserValves`**: 用户级配置(优先级更高,可覆盖全局)。
```python
class Filter:
@@ -113,7 +116,7 @@ class Filter:
**定位**:在消息下方添加按钮,用户点击触发。
**高级用法:前端执行 JavaScript (文件下载示例)**
#### 高级用法:前端执行 JavaScript (文件下载示例)
```python
import base64
@@ -138,11 +141,11 @@ async def action(self, body, __event_call__):
**定位**:中间件,拦截并修改请求/响应。
* **`inlet`**: 请求前。用于注入上下文、修改模型参数。
* **`outlet`**: 响应后。用于格式化输出、保存日志。
* **`stream`**: 流式处理中。用于实时敏感词过滤。
* **`inlet`**: 请求前。用于注入上下文、修改模型参数。
* **`outlet`**: 响应后。用于格式化输出、保存日志。
* **`stream`**: 流式处理中。用于实时敏感词过滤。
**示例:注入环境变量**
#### 示例:注入环境变量
```python
async def inlet(self, body, __metadata__):
@@ -159,7 +162,7 @@ async def inlet(self, body, __metadata__):
**定位**:自定义模型/代理。
**示例:简单的 OpenAI 代理**
#### 示例:简单的 OpenAI 代理
```python
import requests
@@ -180,11 +183,14 @@ class Pipe:
## 4. 高级开发模式 {: #4-advanced-patterns }
### 4.1 Pipe 与 Filter 协同
利用 `__request__.app.state` 在不同插件间共享数据。
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: 读取 `search_results` 并将其格式化为引用链接附加到回复末尾。
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: 读取 `search_results` 并将其格式化为引用链接附加到回复末尾。
### 4.2 异步后台任务
不阻塞用户响应,在后台执行耗时操作(如生成总结、存库)。
```python
@@ -205,7 +211,7 @@ async def background_job(self, chat_id):
#### 工作流程
```
```text
┌──────────────────────────────────────────────────────────────┐
│ 1. Python Action │
│ ├── 分析消息内容 │
@@ -297,10 +303,10 @@ async def action(self, body, __event_call__, __metadata__, ...):
#### 优势
- **纯 Markdown 输出**:结果是标准的 Markdown 图片语法,无需 HTML 代码块
- **自包含**:图片以 Base64 Data URL 嵌入,无外部依赖
- **持久化**:通过 API 回写,消息重新加载后图片仍然存在
- **跨平台**:任何支持 Markdown 图片的客户端都能显示
* **纯 Markdown 输出**:结果是标准的 Markdown 图片语法,无需 HTML 代码块
* **自包含**:图片以 Base64 Data URL 嵌入,无外部依赖
* **持久化**:通过 API 回写,消息重新加载后图片仍然存在
* **跨平台**:任何支持 Markdown 图片的客户端都能显示
#### HTML 注入 vs JS 渲染嵌入 Markdown
@@ -315,20 +321,23 @@ async def action(self, body, __event_call__, __metadata__, ...):
#### 参考实现
- `plugins/actions/infographic/infographic.py` - 基于 AntV + Data URL 的生产级实现
* `plugins/actions/infographic/infographic.py` - 基于 AntV + Data URL 的生产级实现
## 5. 最佳实践与设计原则 {: #5-best-practices }
### 5.1 命名与定位
* **简短有力**:如 "闪记卡", "精读"。避免 "文本分析助手" 这种泛词。
* **功能互补**:不要重复造轮子,明确你的插件解决了什么特定问题
* **简短有力**:如 "闪记卡", "精读"。避免 "文本分析助手" 这种泛词
* **功能互补**:不要重复造轮子,明确你的插件解决了什么特定问题。
### 5.2 用户体验 (UX)
* **反馈及时**:耗时操作前先发送 `notification` ("正在生成...")。
* **视觉美观**Action 输出 HTML 时,使用现代化的 CSS圆角、阴影、渐变
* **智能引导**:检测到文本过短时,提示用户"建议输入更多内容以获得更好结果"
* **反馈及时**:耗时操作前先发送 `notification` ("正在生成...")
* **视觉美观**Action 输出 HTML 时,使用现代化的 CSS圆角、阴影、渐变
* **智能引导**:检测到文本过短时,提示用户"建议输入更多内容以获得更好结果"。
### 5.3 错误处理
永远不要让插件静默失败。捕获异常并通过 `__event_emitter__` 告知用户。
```python
@@ -343,8 +352,76 @@ except Exception as e:
---
## 6. 故障排查 {: #6-troubleshooting }
## 6. 仓库规范openwebui-extensions {: #6-repo-standards }
* **HTML 不显示?** 确保包裹在 ` ```html ... ``` ` 代码块中。
* **数据库报错?** 检查是否在 `async` 函数中直接调用了同步的 DB 方法,请使用 `asyncio.to_thread`
* **参数未生效?** 检查 `Valves` 定义是否正确,以及是否被 `UserValves` 覆盖。
### 6.1 单文件 i18n 规范
本仓库要求每个插件采用**单文件源码 + 内置多语言**方案,禁止按语言拆分多个 `.py` 文件。
* 代码路径规范:`plugins/{type}/{name}/{name}.py`
* 文档规范:必须同时提供 `README.md``README_CN.md`
### 6.2 上下文访问规范(必选)
优先通过 `_get_user_context``_get_chat_context` 提取上下文,避免直接硬编码读取 `__user__``body` 字段。
### 6.3 事件与日志规范
* 用状态/通知事件给用户反馈进度。
* 前端调试优先使用 `execute` 注入的控制台日志。
* 后端统一使用 Python `logging`,生产代码避免 `print()`
### 6.4 前端语言探测防卡死
通过 `__event_call__` 获取前端语言时,必须同时满足:
* JS 端 `try...catch` 并保证返回值
* 后端 `asyncio.wait_for(..., timeout=2.0)`
这样可以避免前端异常导致后端永久等待。
### 6.5 Copilot SDK 工具参数定义
开发 Copilot SDK 工具时,应使用 `pydantic.BaseModel` 显式声明参数,并在 `define_tool(...)` 中通过 `params_type` 传入。
### 6.6 Copilot SDK 流式输出格式
* 思考过程使用原生 `<think>...</think>`
* 正文或工具卡片输出前,必须先闭合 `</think>`
* 工具卡片使用 `<details type="tool_calls" ...>` 原生结构。
* `arguments``result` 属性中的双引号必须转义为 `&quot;`
### 6.7 从 `plugins/` 全量提炼的关键开发知识
* **输入与上下文**:统一做多模态文本抽取;优先 `_get_user_context` / `_get_chat_context`;前端语言探测必须 `wait_for` 超时保护。
* **长任务反馈**:执行前立即发送 `status/notification`,过程分阶段汇报,失败时用户提示简洁、后台日志完整。
* **HTML/渲染输出**:使用固定包装器与插入点,支持覆盖与合并两种模式;主题跟随父页面与系统主题。
* **前端导出闭环**:离屏渲染 SVG/PNG -> 上传 `/api/v1/files/` -> 事件更新 + 持久化更新,避免刷新丢失。
* **DOCX 生产模式**`TITLE_SOURCE` 多级回退;导出前剔除 reasoningLaTeX 转 OMML支持引用锚点与参考文献。
* **文件访问回退链**DB 内联 -> S3 -> 本地路径变体 -> 公网 URL -> 内部 API -> 原始字段,并在每层限制字节上限。
* **Filter 单例安全**:禁止在 `self` 保存请求态;上下文压缩采用 inlet/outlet 双阶段 + 异步后台任务。
* **工具与工作区安全**:工具参数用 `params_type` 显式建模;路径解析后必须二次校验在 workspace 根目录内。
* **文件交付标准**:本地生成 -> 发布工具 -> 返回 `/api/v1/files/{id}/content`,并带 `skip_rag=true` 元数据。
* **MoE 聚合优化**:识别聚合提示词后重写为结构化综合分析任务,并可在聚合阶段切换模型。
### 6.8 Copilot 工程化配置GitHub Copilot + Gemini CLI + 反重力开发)
统一工程化配置请参考:
* `docs/development/copilot-engineering-plan.md`
* `docs/development/copilot-engineering-plan.zh.md`
该设计文档规定了:
* 工具参数建模与路由规则
* 文件创建与发布协议
* 可回滚的高迭代交付模式
* 流式输出与工具卡片兼容要求
---
## 7. 故障排查 {: #7-troubleshooting }
* **HTML 不显示?** 确保包裹在 ` ```html ... ``` ` 代码块中。
* **数据库报错?** 检查是否在 `async` 函数中直接调用了同步的 DB 方法,请使用 `asyncio.to_thread`
* **参数未生效?** 检查 `Valves` 定义是否正确,以及是否被 `UserValves` 覆盖。

View File

@@ -1,50 +1,46 @@
# 开源项目重组实施计划
# Implementation Plan (Current)
## 1. 目标
`openwebui-extras` 打造为一个 **OpenWebUI 增强功能集合库**,专注于分享个人开发和收集的优质插件、提示词,而非作为一个独立的 Python 应用程序发布。
## 1. Objective
## 2. 当前状态分析
- **定位明确**项目核心价值在于内容Plugins, Prompts, Docs而非运行环境。
- **结构已优化**
- `plugins/`:核心插件资源。
- `prompts/`:提示词资源。
- `docs/`:详细的使用和开发文档。
- `scripts/`:辅助工具脚本(如本地测试用的 `run.py`)。
- **已移除不必要文件**:移除了 `requirements.txt`,避免用户误以为需要配置 Python 环境。
Define an engineering-ready design baseline for OpenWebUI plugin development that:
## 3. 重组方案
- uses GitHub Copilot as the primary coding agent,
- supports Gemini CLI as a secondary execution/research lane,
- adopts antigravity development mode for reversible, low-risk iteration.
### 3.1 目录结构
保持当前的清晰结构,强调“拿来即用”:
## 2. Current Decision
```
openwebui-extras/
├── docs/ # 文档与教程
├── plugins/ # 插件库 (核心资源)
│ ├── actions/
│ ├── filters/
│ ├── pipelines/
│ └── pipes/
├── prompts/ # 提示词库 (核心资源)
├── scripts/ # 维护者工具 (非用户必须)
├── LICENSE # MIT 许可证
├── README.md # 项目入口与资源索引
└── index.html # 项目展示页
```
The active design document is:
### 3.2 核心调整
1. **移除依赖管理**:删除了 `requirements.txt`。用户不需要 `pip install` 任何东西,只需下载对应的 `.py``.md` 文件导入 OpenWebUI 即可。
2. **文档侧重**README 和文档将侧重于“如何下载”和“如何导入”,而不是“如何安装项目”。
- `docs/development/copilot-engineering-plan.md`
- `docs/development/copilot-engineering-plan.zh.md`
### 3.3 后续建议
1. **资源索引**:建议在 `README.md` 中维护一个高质量的插件/提示词索引表,方便用户快速查找。
2. **贡献指南**:制定简单的 `CONTRIBUTING.md`,告诉其他人如何提交他们的插件或提示词(例如:只需提交文件到对应目录)。
3. **版本控制**:虽然不需要 Python 环境,但建议在插件文件的头部注释中保留版本号和兼容性说明(如 `Compatible with OpenWebUI v0.3.x`)。
This file is retained as a stable pointer to avoid design drift.
## 4. 发布流程
1. **提交更改**`git add . && git commit -m "Update project structure for resource sharing"`
2. **推送到 GitHub**
3. **宣传**:在 OpenWebUI 社区分享此仓库链接。
## 3. Engineering Baseline
- Single-file i18n plugin code architecture.
- Bilingual documentation contract.
- Copilot SDK tool schema discipline (`params_type`).
- Gemini CLI output normalization before merge.
- Workspace file sandbox + publish protocol.
- Streaming compatibility with native `<think>` and `<details type="tool_calls">`.
## 4. File Creation & Delivery Baseline
- Create artifacts in workspace-scoped paths.
- Publish artifacts via workspace publish flow.
- Return and display `/api/v1/files/{id}/content` links for delivery.
## 5. Maintenance Rule
Any update to plugin engineering standards must be reflected in:
1. `docs/development/copilot-engineering-plan.md`
2. `docs/development/copilot-engineering-plan.zh.md`
3. `docs/development/plugin-guide.md`
4. `docs/development/plugin-guide.zh.md`
---
*生成时间2025-12-19*
Updated: 2026-02-23

View File

@@ -4,15 +4,17 @@
## 📚 Table of Contents
1. [Quick Start](#1-quick-start)
2. [Core Concepts & SDK Details](#2-core-concepts--sdk-details)
3. [Deep Dive into Plugin Types](#3-deep-dive-into-plugin-types)
* [Action](#31-action)
* [Filter](#32-filter)
* [Pipe](#33-pipe)
4. [Advanced Development Patterns](#4-advanced-development-patterns)
5. [Best Practices & Design Principles](#5-best-practices--design-principles)
6. [Troubleshooting](#6-troubleshooting)
1. [Quick Start](#1-quick-start)
2. [Core Concepts & SDK Details](#2-core-concepts--sdk-details)
3. [Deep Dive into Plugin Types](#3-deep-dive-into-plugin-types)
* [Action](#31-action)
* [Filter](#32-filter)
* [Pipe](#33-pipe)
4. [Advanced Development Patterns](#4-advanced-development-patterns)
5. [Best Practices & Design Principles](#5-best-practices--design-principles)
6. [Repository Standards (openwebui-extensions)](#6-repository-standards-openwebui-extensions)
7. [Custom Agent Design Recommendations](#7-custom-agent-design-recommendations)
8. [Troubleshooting](#8-troubleshooting)
---
@@ -21,9 +23,10 @@
### 1.1 What are OpenWebUI Plugins?
OpenWebUI Plugins (officially called "Functions") are the primary way to extend the platform's capabilities. Running in a backend Python environment, they allow you to:
* 🔌 **Integrate New Models**: Connect to Claude, Gemini, or custom RAGs via Pipes.
* 🎨 **Enhance Interaction**: Add buttons (e.g., "Export", "Generate Chart") next to messages via Actions.
* 🔧 **Intervene in Processes**: Modify data before requests or after responses (e.g., inject context, filter sensitive words) via Filters.
* 🔌 **Integrate New Models**: Connect to Claude, Gemini, or custom RAGs via Pipes.
* 🎨 **Enhance Interaction**: Add buttons (e.g., "Export", "Generate Chart") next to messages via Actions.
* 🔧 **Intervene in Processes**: modify data before requests or after responses (e.g., inject context, filter sensitive words) via Filters.
### 1.2 Your First Plugin (Hello World)
@@ -69,9 +72,10 @@ class Action:
### 2.1 ⚠️ Important: Sync vs Async
OpenWebUI plugins run within an `asyncio` event loop.
* **Principle**: All I/O operations (database, file, network) must be non-blocking.
* **Pitfall**: Calling synchronous methods directly (e.g., `time.sleep`, `requests.get`) will freeze the entire server.
* **Solution**: Wrap synchronous calls using `await asyncio.to_thread(sync_func, ...)`.
* **Principle**: All I/O operations (database, file, network) must be non-blocking.
* **Pitfall**: Calling synchronous methods directly (e.g., `time.sleep`, `requests.get`) will freeze the entire server.
* **Solution**: Wrap synchronous calls using `await asyncio.to_thread(sync_func, ...)`.
### 2.2 Core Parameters
@@ -88,8 +92,8 @@ All plugin methods (`inlet`, `outlet`, `pipe`, `action`) support injecting the f
### 2.3 Configuration System (Valves)
* **`Valves`**: Global admin configuration.
* **`UserValves`**: User-level configuration (higher priority, overrides global).
* **`Valves`**: Global admin configuration.
* **`UserValves`**: User-level configuration (higher priority, overrides global).
```python
class Filter:
@@ -113,7 +117,7 @@ class Filter:
**Role**: Adds buttons below messages that trigger upon user click.
**Advanced Usage: Execute JavaScript on Frontend (File Download Example)**
#### Advanced Usage: Execute JavaScript on Frontend (File Download Example)
```python
import base64
@@ -138,11 +142,11 @@ async def action(self, body, __event_call__):
**Role**: Middleware that intercepts and modifies requests/responses.
* **`inlet`**: Before request. Used for injecting context, modifying model parameters.
* **`outlet`**: After response. Used for formatting output, logging.
* **`stream`**: During streaming. Used for real-time sensitive word filtering.
* **`inlet`**: Before request. Used for injecting context, modifying model parameters.
* **`outlet`**: After response. Used for formatting output, logging.
* **`stream`**: During streaming. Used for real-time sensitive word filtering.
**Example: Injecting Environment Variables**
#### Example: Injecting Environment Variables
```python
async def inlet(self, body, __metadata__):
@@ -159,7 +163,7 @@ async def inlet(self, body, __metadata__):
**Role**: Custom Model/Agent.
**Example: Simple OpenAI Wrapper**
#### Example: Simple OpenAI Wrapper
```python
import requests
@@ -180,11 +184,14 @@ class Pipe:
## 4. Advanced Development Patterns
### 4.1 Pipe & Filter Collaboration
Use `__request__.app.state` to share data between plugins.
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: Read `search_results` and format them as citation links appended to the response.
* **Pipe**: `__request__.app.state.search_results = [...]`
* **Filter (Outlet)**: Read `search_results` and format them as citation links appended to the response.
### 4.2 Async Background Tasks
Execute time-consuming operations (e.g., summarization, database storage) in the background without blocking the user response.
```python
@@ -204,15 +211,18 @@ async def background_job(self, chat_id):
## 5. Best Practices & Design Principles
### 5.1 Naming & Positioning
* **Short & Punchy**: e.g., "FlashCard", "DeepRead". Avoid generic terms like "Text Analysis Assistant".
* **Complementary**: Don't reinvent the wheel; clarify what specific problem your plugin solves.
* **Short & Punchy**: e.g., "FlashCard", "DeepRead". Avoid generic terms like "Text Analysis Assistant".
* **Complementary**: Don't reinvent the wheel; clarify what specific problem your plugin solves.
### 5.2 User Experience (UX)
* **Timely Feedback**: Send a `notification` ("Generating...") before time-consuming operations.
* **Visual Appeal**: When Action outputs HTML, use modern CSS (rounded corners, shadows, gradients).
* **Smart Guidance**: If text is too short, prompt the user: "Suggest entering more content for better results".
* **Timely Feedback**: Send a `notification` ("Generating...") before time-consuming operations.
* **Visual Appeal**: When Action outputs HTML, use modern CSS (rounded corners, shadows, gradients).
* **Smart Guidance**: If text is too short, prompt the user: "Suggest entering more content for better results".
### 5.3 Error Handling
Never let a plugin fail silently. Catch exceptions and inform the user via `__event_emitter__`.
```python
@@ -227,8 +237,127 @@ except Exception as e:
---
## 6. Troubleshooting
## 6. Repository Standards (openwebui-extensions)
* **HTML not showing?** Ensure it's wrapped in a ` ```html ... ``` ` code block.
* **Database error?** Check if you called synchronous DB methods directly in an `async` function; use `asyncio.to_thread`.
* **Parameters not working?** Check if `Valves` are defined correctly and if they are being overridden by `UserValves`.
### 6.1 Single-file i18n Requirement
In this repository, each plugin must use a **single source file** with built-in i18n logic. Do not split source code by language.
* Required pattern: `plugins/{type}/{name}/{name}.py`
* Required docs: `README.md` + `README_CN.md`
### 6.2 Safe Context Access (Required)
Prefer helper methods like `_get_user_context` and `_get_chat_context` instead of direct, fragile field access from `__user__` / `body`.
### 6.3 Event and Logging Conventions
* Use status/notification events for user-visible progress.
* Use frontend console debug logs (`execute`) for live debugging during development.
* Use Python `logging` for backend logs; avoid `print()` in production plugin code.
### 6.4 Frontend Language Detection and Timeout Guard
When reading frontend language via `__event_call__`, always use:
* JS `try...catch` fallback return
* backend `asyncio.wait_for(..., timeout=2.0)`
This prevents deadlocks when frontend execution fails.
### 6.5 Copilot SDK Tool Definition
For custom Copilot SDK tools, define explicit parameter schema using a `pydantic.BaseModel` and pass it with `params_type` in `define_tool(...)`.
### 6.6 Copilot SDK Streaming Output Format
* Use native `<think>...</think>` for reasoning output.
* Ensure `</think>` is closed before normal content or tool cards.
* For tool result cards, use native `<details type="tool_calls" ...>` format.
* Escape attribute quotes in `arguments` and `result` as `&quot;`.
### 6.7 Source-derived Production Patterns (Recommended)
The following patterns are extracted from `github_copilot_sdk.py` and `workspace_file_manager.py`:
* **Tool parameter anti-drift**: define tools with `params_type=BaseModel`, and execute with `model_dump(exclude_unset=True)` so missing params do not become explicit `None`.
* **Tool name normalization**: enforce `^[a-zA-Z0-9_-]+$`; if non-ASCII names collapse, use an `md5` suffix fallback to keep registration stable.
* **Workspace sandboxing**: resolve and verify every path stays inside the workspace root to prevent traversal.
* **3-step file delivery**: local write -> `publish_file_from_workspace` -> return `/api/v1/files/{id}/content`, with `skip_rag=true` metadata.
* **Dual upload channel**: prefer API upload (S3-compatible), fallback to DB + local copy.
* **Streaming stability**: close `<think>` before emitting `assistant.message_delta` content.
* **Native tool cards**: emit `<details type="tool_calls">` on `tool.execution_complete` with strict HTML escaping (`&quot;`, newline escaping).
* **TODO persistence linkage**: on successful `update_todo`, sync both `TODO.md` and database state.
### 6.8 Full Source-derived Knowledge Base (from `plugins/`)
The following is a broader extraction from `actions/`, `filters/`, `pipes/`, `pipelines/`, and `tools/`:
* **Action input hygiene**: normalize multimodal message content, strip old plugin HTML blocks (`OPENWEBUI_PLUGIN_OUTPUT`), and enforce minimum text length before expensive model calls.
* **Action i18n hardening**: use `TRANSLATIONS + fallback_map + base-lang fallback` (`fr-CA -> fr-FR`, `en-GB -> en-US`), keep all status/UI/JS strings in i18n keys, and protect `format(**kwargs)` formatting.
* **Frontend language detection (production-safe)**: use priority chain `document.lang -> localStorage(locale/language) -> navigator.language -> profile/request`, and always wrap `__event_call__(execute)` with timeout.
* **Long-running UX pattern**: emit immediate `status + notification`, report staged progress (`analyzing/rendering/saving`), and keep detailed exception data in backend logs.
* **HTML plugin composability**: use insertion markers for style/content/script, support both overwrite (`CLEAR_PREVIOUS_HTML`) and merge mode, and keep wrappers deterministic.
* **Theme-aware iframe rendering**: detect theme from parent meta/class/data-theme with system fallback, and inject theme-aware colors for SVG/PNG export.
* **Client-side render-and-export pipeline**: render offscreen chart/mindmap, export SVG/PNG, upload via `/api/v1/files/`, and persist updates through event API + chat persistence API.
* **DOCX export production patterns**: apply `TITLE_SOURCE` fallback chain (`chat_title -> markdown_title -> user+date`), remove reasoning blocks, convert LaTeX via `latex2mathml + mathml2omml`, and emit citation-aware references/bookmarks.
* **OpenWebUI file retrieval fallback ladder**: DB inline bytes/base64 -> S3 direct read -> local path variants -> public URL -> internal `/api/v1/files/{id}/content` -> raw object attrs, with max-byte guards at every stage.
* **Filter singleton-safe design**: never store request-scoped mutable state on `self`; compute per-request values from `body` and context helpers.
* **Async context compression patterns**: two-phase flow (`inlet` apply summary, `outlet` async generate summary), model-level threshold overrides, fast estimate + precise count near limit, and system-message protection (`effective_keep_first`).
* **Model compatibility guardrails**: skip incompatible model families (e.g., `copilot_sdk` paths) and avoid hardcoded default model IDs.
* **Folder memory pattern**: trigger periodic rule extraction (`every N messages`), replace rules idempotently using block markers (`RULES_BLOCK_START/END`), and optionally update root folder.
* **Tool workspace hardening**: all file APIs (`list/read/write/delete/publish`) must re-check sandbox boundary, enforce size limits, and return user-ready download hints.
* **MoE prompt refiner pattern (pipeline)**: detect aggregation prompts via trigger prefix, parse original query + segmented responses, then rewrite to synthesis-oriented master prompt with optional aggregation model reroute.
### 6.9 Copilot-related Engineering Configuration
To support plugin engineering with **GitHub Copilot + Gemini CLI + antigravity mode**, adopt these controls:
* **Primary/secondary assistant lanes**: Copilot is primary implementation lane; Gemini CLI is secondary draft/verification lane.
* **Single merge contract**: both lanes must pass the same repository constraints (single-file i18n, context helpers, event conventions, release workflow rules).
* **Tool schema discipline**: all Copilot SDK tools use explicit `params_type` with Pydantic models.
* **Antigravity safety**: small reversible edits, timeout guards, fallback routing, and deterministic file/output paths.
* **File creation protocol**: write in workspace scope, publish via workspace publish flow, return `/api/v1/files/{id}/content` for delivery.
Detailed design document:
* `docs/development/copilot-engineering-plan.md`
---
## 7. Custom Agent Design Recommendations
### 7.1 Suggested architecture (for this repo)
* **Orchestrator Pipe**: session lifecycle, model routing, streaming events.
* **Tool Adapter Layer**: unify OpenWebUI Tools / OpenAPI / MCP with param validation and name normalization.
* **Workspace I/O Layer**: sandboxed file operations + publish pipeline.
* **Render Layer**: `<think>` lifecycle, tool cards, status/notification events.
### 7.2 MVP checklist
1. Dual config model: `Valves + UserValves` (user overrides first).
2. Unified context helpers: `_get_user_context` / `_get_chat_context`.
3. At least one artifact-delivery tool (e.g., `publish_file_from_workspace`).
4. Minimal streaming loop: `reasoning_delta`, `message_delta`, `tool.execution_complete`.
5. Unified error reporting via notification events.
### 7.3 Three high-impact agents you can build now
* **Repo Analyst Agent**: output architecture map, risk list, and refactor proposals.
* **Release Draft Agent**: generate Conventional Commit title/body + bilingual release summary.
* **Docs Sync Agent**: compare source/doc versions and output a concrete sync file list.
### 7.4 Implementation priority
* **P0**: Release Draft Agent (highest ROI, lowest risk).
* **P1**: Docs Sync Agent (reduces doc drift).
* **P2**: Repo Analyst Agent (medium/long-term evolution).
---
## 8. Troubleshooting
* **HTML not showing?** Ensure it's wrapped in a ` ```html ... ``` ` code block.
* **Database error?** Check if you called synchronous DB methods directly in an `async` function; use `asyncio.to_thread`.
* **Parameters not working?** Check if `Valves` are defined correctly and if they are being overridden by `UserValves`.

View File

@@ -4,17 +4,17 @@ hide:
- toc
---
# Welcome to OpenWebUI Extras
# Welcome to OpenWebUI Extensions
<div class="hero-section" markdown>
<div class="hero-content" markdown>
# 🚀 Supercharge Your OpenWebUI Experience
**OpenWebUI Extras** is a curated collection of plugins, prompts, and enhancements designed to extend the functionality of [OpenWebUI](https://github.com/open-webui/open-webui).
**OpenWebUI Extensions** is a curated collection of plugins, prompts, and enhancements designed to extend the functionality of [OpenWebUI](https://github.com/open-webui/open-webui).
[Get Started :material-arrow-right:](#quick-navigation){ .md-button .md-button--primary }
[View on GitHub :fontawesome-brands-github:](https://github.com/Fu-Jie/awesome-openwebui){ .md-button }
[View on GitHub :fontawesome-brands-github:](https://github.com/Fu-Jie/openwebui-extensions){ .md-button }
</div>
</div>
@@ -135,6 +135,6 @@ We welcome contributions! Whether it's a new plugin, a helpful prompt, or docume
<div class="footer-stats" markdown>
**OpenWebUI Extras** - Making AI interactions more powerful and productive.
**OpenWebUI Extensions** - Making AI interactions more powerful and productive.
</div>

Some files were not shown because too many files have changed in this diff Show More