> This guide consolidates official documentation, SDK details, and best practices to provide a systematic tutorial for developers, from beginner to expert.
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:
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 `"`.
### 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 (`"`, 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.