feat(github-copilot-sdk): release v0.10.0 with native prompt restoration and live todo widget
- Restore native Copilot CLI prompts for authentic Plan Mode behavior - Add SQLite-backed session management for state persistence via system prompt - Implement Adaptive Autonomy (Agent chooses planning vs direct execution) - Fix OpenWebUI custom tool context injection for v0.8.x compatibility - Add compact Live TODO widget synchronized with session.db - Upgrade SDK to github-copilot-sdk==0.1.30 - Remove legacy mode switch RPC calls (moved to prompt-driven orchestration) - Fix intent status localization and widget whitespace optimization - Sync bilingual READMEs and all documentation mirrors to v0.10.0
This commit is contained in:
83
.agent/learnings/openwebui-tool-injection.md
Normal file
83
.agent/learnings/openwebui-tool-injection.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# OpenWebUI Tool Parameter Injection
|
||||
|
||||
> Discovered: 2026-03-05
|
||||
|
||||
## Context
|
||||
|
||||
When OpenWebUI loads a Python Tool and calls one of its functions (e.g. `generate_mind_map`),
|
||||
it automatically matches parameters from an `extra_params` dict against the function's
|
||||
signature **by name**. This is done in:
|
||||
|
||||
```
|
||||
open_webui/utils/tools.py → get_async_tool_function_and_apply_extra_params()
|
||||
```
|
||||
|
||||
The lookup is: `extra_params = {k: v for k, v in extra_params.items() if k in sig.parameters}`
|
||||
|
||||
## Finding
|
||||
|
||||
A Tool function declares its dependencies via its parameter names. Common injected names:
|
||||
|
||||
| Parameter Name | What it contains |
|
||||
|-----------------------|---------------------------------------------------|
|
||||
| `__user__` | User context dict (id, email, role, name) |
|
||||
| `__event_emitter__` | Async callable to emit status/notification events |
|
||||
| `__event_call__` | Async callable for JS `__event_call__` roundtrips |
|
||||
| `__request__` | Request-like object (must have `.app.state.MODELS`) |
|
||||
| `__metadata__` | Dict: `{model, base_model_id, chat_id, ...}` |
|
||||
| `__messages__` | Full conversation history list |
|
||||
| `__chat_id__` | Current chat UUID |
|
||||
| `__message_id__` | Current message UUID |
|
||||
| `__session_id__` | Current session UUID |
|
||||
| `__files__` | Files attached to the current message |
|
||||
| `__task__` | Task type string (e.g. `title_generation`) |
|
||||
| `body` | Raw request body dict (non-dunder variant) |
|
||||
| `request` | Request object (non-dunder variant) |
|
||||
|
||||
## Key Rule
|
||||
|
||||
**`extra_params` must contain ALL keys a Tool's function signature declares.**
|
||||
If a key is missing from `extra_params`, the parameter silently receives its default
|
||||
value (e.g. `{}` for `__metadata__`). This means the Tool appears to work but
|
||||
gets empty/wrong context.
|
||||
|
||||
## Solution / Pattern
|
||||
|
||||
When a Pipe calls an OpenWebUI Tool, it must populate `extra_params` with **all** the above:
|
||||
|
||||
```python
|
||||
extra_params = {
|
||||
"__request__": request, # Must have app.state.MODELS populated!
|
||||
"request": request, # Non-dunder alias
|
||||
"__user__": user_data,
|
||||
"__event_emitter__": __event_emitter__,
|
||||
"__event_call__": __event_call__,
|
||||
"__messages__": messages,
|
||||
"__metadata__": __metadata__ or {},
|
||||
"__chat_id__": chat_id,
|
||||
"__message_id__": message_id,
|
||||
"__session_id__": session_id,
|
||||
"__files__": files,
|
||||
"__task__": task,
|
||||
"__task_body__": task_body,
|
||||
"body": body, # Non-dunder alias
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Model Resolution
|
||||
|
||||
Tools that call `generate_chat_completion` internally need a **valid model ID**.
|
||||
When the conversation is running under a Pipe/Manifold model (e.g. `github_copilot.gpt-4o`),
|
||||
the Tool's `valves.MODEL_ID` must be a *real* model known to the system.
|
||||
|
||||
`generate_chat_completion` validates model IDs against `request.app.state.MODELS`.
|
||||
➡️ That dict **must be populated** from the database (see `openwebui-mock-request.md`).
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Tools call `generate_chat_completion` with a `request` arg that must be the full Mock Request.
|
||||
- If `app.state.MODELS` is empty, even a correctly-spelled model ID will cause "Model not found".
|
||||
- `__metadata__['model']` can be a **dict** (from DB) **or a string** (manifold ID). Tools must
|
||||
handle both types.
|
||||
- For manifold models not in the DB, strip the prefix: `github_copilot.gpt-4o` → `gpt-4o`.
|
||||
Reference in New Issue
Block a user