Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions .github/workflows/validate-quick-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Validate Quick Actions

on:
push:
paths:
- "functions/actions/quick-actions/**"
- ".github/workflows/validate-quick-actions.yml"
pull_request:
paths:
- "functions/actions/quick-actions/**"
- ".github/workflows/validate-quick-actions.yml"

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install runtime dependency
run: python -m pip install "pydantic>=2,<3"

- name: Compile and smoke-test Quick Actions
shell: bash
run: |
set -euo pipefail
python -m py_compile functions/actions/quick-actions/quick_actions.py
python - <<'PY'
import importlib.util
import sys
from pathlib import Path

path = Path("functions/actions/quick-actions/quick_actions.py")
spec = importlib.util.spec_from_file_location("quick_actions", path)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)

assert len(module.ACTION_SPECS) == 48, len(module.ACTION_SPECS)
assert len({item.id for item in module.ACTION_SPECS}) == 48
missing_fr = [item.id for item in module.ACTION_SPECS if item.id not in module.FR_ACTIONS]
assert not missing_fr, f"Missing French translations: {missing_fr}"

human = {item.id for item in module.ACTION_SPECS if item.category == "Humanize"}
assert human == {
"humanize",
"humanize_professional",
"humanize_conversational",
"remove_ai_tells",
"match_voice",
}

action = module.Action()
user_valves = action.UserValves()
for context in ("general", "writing", "research", "code", "data", "long"):
choices, _ = action._visible_choices(context, user_valves, "en")
assert choices, context

custom = action._parse_custom_actions(
"Manager brief :: Summarize this for management.\n"
"Audience version :: Rewrite this for {input:Audience}.",
source="user",
limit=10,
)
assert len(custom) == 2
assert custom[1].needs_input is True
assert action._custom_input_label(custom[1].prompt) == "Audience"

text = path.read_text(encoding="utf-8")
assert "innerHTML" not in text
assert "eval(" not in text
assert "new Function" not in text
print("Quick Actions Python smoke tests passed")
PY

- name: Validate generated browser JavaScript
shell: bash
run: |
set -euo pipefail
python - <<'PY'
import importlib.util
import json
import sys
from pathlib import Path

path = Path("functions/actions/quick-actions/quick_actions.py")
spec = importlib.util.spec_from_file_location("quick_actions", path)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
action = module.Action()

payload = json.dumps({
"context": "general",
"choices": [],
"maxSuggestions": 3,
"timeoutMs": 1000,
"ui": module.UI_CATALOG["en"],
}, ensure_ascii=True, separators=(",", ":"))

Path("/tmp/qa-menu.js").write_text(
"async function check(){\n" + action._menu_js(payload) + "\n}\n",
encoding="utf-8",
)
Path("/tmp/qa-composer.js").write_text(
"async function check(){\n" + action._composer_js(json.dumps({
"text": "test",
"submit": False,
"force": False,
})) + "\n}\n",
encoding="utf-8",
)
PY
node --check /tmp/qa-menu.js
node --check /tmp/qa-composer.js
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This repository contains independently versioned Open WebUI extensions. Plugin-specific release notes live next to each implementation when they need more detail.

## 2026-08-28

### Quick Actions 3.0.0

Added the first public Action Function to the repository: a compact context-aware Quick Actions menu for assistant responses. The release includes response rewriting and creation workflows, verification and follow-up actions, code/data/study helpers, a dedicated Humanize section, English/French built-in UI and prompts, admin Team actions, per-user My actions, custom `{input}` actions, safe composer preview/send modes, draft protection, older-message targeting, mobile/desktop layouts, and light/dark accessibility handling.

## 2026-08-26

### Repository structure
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The goal is simple: keep each extension portable, documented, and safe to review
| Extension | Type | Version | Status | Purpose |
| --- | --- | --- | --- | --- |
| [Study Mode](functions/filters/study-mode/) | Filter | 1.0.0 | Stable | Guided learning, Socratic tutoring, adaptive pacing, native `ask_user` support, and interactive quizzes |
| [Quick Actions](functions/actions/quick-actions/) | Action | 3.0.0 | Stable | Compact context-aware response transformations, Humanize actions, verification, creation workflows, English/French UI, and user/team custom actions |
| [RAGFlow Advanced Connector](tools/ragflow/) | Tool | 3.0.0 | Stable | RAGFlow retrieval, dataset discovery, document search, and configurable retrieval controls |

## Repository structure
Expand Down Expand Up @@ -39,7 +40,11 @@ The goal is simple: keep each extension portable, documented, and safe to review
├── pipes/
│ └── README.md
├── actions/
│ └── README.md
│ ├── README.md
│ └── quick-actions/
│ ├── README.md
│ ├── CHANGELOG.md
│ └── quick_actions.py
└── events/
└── README.md
```
Expand Down Expand Up @@ -67,7 +72,7 @@ Each extension has a dedicated README with its setup steps. In general:

The repository follows current Open WebUI plugin APIs. Individual extensions declare their own compatibility requirements.

Study Mode currently declares **Open WebUI 0.11.1 or newer** because its interactive quiz experience uses the current Filter event and Rich UI APIs.
Study Mode and Quick Actions currently declare **Open WebUI 0.11.1 or newer** because they use the current Function event APIs and interactive browser-side UI capabilities.

## Security

Expand Down Expand Up @@ -97,6 +102,7 @@ Examples:

```text
study-mode-v1.0.0
quick-actions-v3.0.0
ragflow-v3.0.0
```

Expand Down
9 changes: 8 additions & 1 deletion functions/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ Typical uses include:
- trigger a workflow;
- apply a message-specific transformation.

## Available Actions

| Action | Version | Status | Purpose |
| --- | --- | --- | --- |
| [Quick Actions](quick-actions/) | 3.0.0 | Stable | Compact context-aware response transformations, Humanize actions, verification, creation workflows, English/French UI, and user/team custom actions |

## Directory convention

```text
actions/
└── action-name/
├── README.md
├── CHANGELOG.md
└── action_name.py
```

No Action implementations are included yet.
Action implementations should keep user-triggered behavior explicit, document any browser-side `execute` usage, and avoid hidden external calls that are not clear from the source and README.
16 changes: 16 additions & 0 deletions functions/actions/quick-actions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Changelog

## 3.0.0

- Added Humanize section with five writing transformations.
- Added complete English/French built-in UI and prompt catalogs.
- Added admin language default and user language override.
- Replaced many admin section toggles with one native multiselect.
- Replaced user code/data/study toggles with a native hidden-sections multiselect.
- Added action-specific inline SVG icons.
- Reduced menu density and moved Explore into More.
- Improved light/dark/system/high-contrast/reduced-motion behavior.
- Added named custom inputs using `{input:Label}`.
- Changed compact-menu failure fallback to look like an intentional custom instruction.
- Fixed intentional menu cancel so it no longer opens the fallback input dialog.
- Preserved safe preview mode, draft protection, concurrency cancellation, timeout cleanup, and older-message targeting.
Loading
Loading