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
This commit is contained in:
fujie
2026-02-24 15:13:52 +08:00
parent 2da934dd92
commit 377534e6c9
20 changed files with 1675 additions and 337 deletions

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.