@mseep/open-computer-use 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.coderabbit.yaml +25 -0
- package/.dockerignore +95 -0
- package/.env.example +137 -0
- package/.githooks/pre-commit +68 -0
- package/.github/CODEOWNERS +125 -0
- package/.github/ISSUE_TEMPLATE/adr-proposal.md +41 -0
- package/.github/ISSUE_TEMPLATE/bug-report.md +49 -0
- package/.github/ISSUE_TEMPLATE/component-proposal.md +38 -0
- package/.github/ISSUE_TEMPLATE/config.yml +15 -0
- package/.github/ISSUE_TEMPLATE/dependency-proposal.md +59 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
- package/.github/ISSUE_TEMPLATE/nfr-proposal.md +44 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- package/.github/codeql/codeql-config.yml +11 -0
- package/.github/codeql/extensions/security-models/python-sanitizers.model.yml +17 -0
- package/.github/codeql/extensions/security-models/qlpack.yml +7 -0
- package/.github/dependabot.yml +23 -0
- package/.github/security-exceptions.yml +23 -0
- package/.github/workflows/build.yml +420 -0
- package/.github/workflows/codeql.yml +33 -0
- package/.github/workflows/contracts-lint.yml +90 -0
- package/.github/workflows/docs-lint.yml +151 -0
- package/.github/workflows/helm.yml +131 -0
- package/.github/workflows/identity-lint.yml +30 -0
- package/.github/workflows/release-chart.yml +177 -0
- package/.github/workflows/release.yml +95 -0
- package/.github/workflows/security.yml +332 -0
- package/.github/workflows/stale.yml +31 -0
- package/.github/workflows/supply-chain.yml +242 -0
- package/.gitleaks.toml +53 -0
- package/.markdownlint.yaml +51 -0
- package/.semgrepignore +85 -0
- package/.vale/styles/Architecture/ap13-data-class-substrate.yml +12 -0
- package/.vale/styles/Architecture/banned-phrases.yml +23 -0
- package/.vale/styles/Architecture/banned-vocab.yml +23 -0
- package/.vale/styles/Architecture/marketing-tone.yml +19 -0
- package/.vale.ini +18 -0
- package/CHANGELOG.md +411 -0
- package/CLAUDE.md +218 -0
- package/CONTRIBUTING.md +82 -0
- package/Dockerfile +676 -0
- package/LICENSE +98 -0
- package/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +21 -0
- package/NOTICE +36 -0
- package/README.md +516 -0
- package/SECURITY.md +45 -0
- package/THIRD-PARTY-LICENSES.md +14 -0
- package/apt-packages.txt +108 -0
- package/computer-use-server/.dockerignore +13 -0
- package/computer-use-server/Dockerfile +44 -0
- package/computer-use-server/README.md +84 -0
- package/computer-use-server/app.py +1544 -0
- package/computer-use-server/bin/list-subagent-models +449 -0
- package/computer-use-server/cli-defaults/README.md +31 -0
- package/computer-use-server/cli-defaults/codex.json +7 -0
- package/computer-use-server/cli-defaults/opencode.json +18 -0
- package/computer-use-server/cli_adapters/__init__.py +46 -0
- package/computer-use-server/cli_adapters/claude.py +163 -0
- package/computer-use-server/cli_adapters/codex.py +163 -0
- package/computer-use-server/cli_adapters/opencode.py +169 -0
- package/computer-use-server/cli_adapters/result.py +34 -0
- package/computer-use-server/cli_runtime.py +316 -0
- package/computer-use-server/context_vars.py +24 -0
- package/computer-use-server/docker_manager.py +1100 -0
- package/computer-use-server/docs_html.py +12 -0
- package/computer-use-server/mcp_resources.py +170 -0
- package/computer-use-server/mcp_tools.py +1430 -0
- package/computer-use-server/requirements.txt +17 -0
- package/computer-use-server/security.py +50 -0
- package/computer-use-server/skill_manager.py +664 -0
- package/computer-use-server/static/browser-viewer.js +445 -0
- package/computer-use-server/static/chart.umd.js +14 -0
- package/computer-use-server/static/docs.html +203 -0
- package/computer-use-server/static/github-dark.min.css +10 -0
- package/computer-use-server/static/github.min.css +10 -0
- package/computer-use-server/static/highlight.min.js +1213 -0
- package/computer-use-server/static/highlightjs-line-numbers.min.js +1 -0
- package/computer-use-server/static/icons.js +74 -0
- package/computer-use-server/static/jszip.min.js +13 -0
- package/computer-use-server/static/katex/auto-render.min.js +1 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/computer-use-server/static/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/computer-use-server/static/katex/katex.min.css +1 -0
- package/computer-use-server/static/katex/katex.min.js +1 -0
- package/computer-use-server/static/locale.js +242 -0
- package/computer-use-server/static/mammoth.browser.min.js +21 -0
- package/computer-use-server/static/marked.min.js +6 -0
- package/computer-use-server/static/mermaid.min.js +2811 -0
- package/computer-use-server/static/pdf.min.js +22 -0
- package/computer-use-server/static/pdf.worker.min.js +22 -0
- package/computer-use-server/static/pptxviewjs.min.js +1 -0
- package/computer-use-server/static/preact-htm.min.js +1 -0
- package/computer-use-server/static/preview.css +1030 -0
- package/computer-use-server/static/preview.js +1522 -0
- package/computer-use-server/static/xlsx.full.min.js +22 -0
- package/computer-use-server/static/xterm-addon-fit.min.js +2 -0
- package/computer-use-server/static/xterm-addon-web-links.min.js +2 -0
- package/computer-use-server/static/xterm.css +218 -0
- package/computer-use-server/static/xterm.min.js +2 -0
- package/computer-use-server/system_prompt.py +761 -0
- package/computer-use-server/uploads.py +82 -0
- package/contracts/README.md +53 -0
- package/contracts/audit/audit-fanin.asyncapi.yaml +407 -0
- package/contracts/exec/exec-channel.schema.json +240 -0
- package/contracts/mcp/2025-06-18/ocu-constraints.schema.json +178 -0
- package/contracts/storage/file-artifact-api.schema.json +390 -0
- package/contracts/storage/file-ops.schema.json +217 -0
- package/contracts/storage/mount-config.schema.json +197 -0
- package/cron/Dockerfile +15 -0
- package/cron/cleanup-quick.sh +21 -0
- package/cron/cleanup.sh +127 -0
- package/data/outputs/.gitkeep +0 -0
- package/data/uploads/.gitkeep +0 -0
- package/docker-compose.test.yml +54 -0
- package/docker-compose.webui.yml +77 -0
- package/docker-compose.yml +96 -0
- package/docs/CLOUD.md +29 -0
- package/docs/COMPARISON.md +128 -0
- package/docs/DOCKER.md +469 -0
- package/docs/DYNAMIC-SKILLS.md +77 -0
- package/docs/FEATURES.md +100 -0
- package/docs/INSTALL.md +111 -0
- package/docs/KNOWN-BUGS.md +86 -0
- package/docs/MCP.md +320 -0
- package/docs/SCREENSHOTS.md +39 -0
- package/docs/SKILLS-USER-GUIDE.md +86 -0
- package/docs/SKILLS.md +483 -0
- package/docs/TERMINAL-TAB.md +56 -0
- package/docs/architecture/02-trust-boundaries.md +224 -0
- package/docs/architecture/03-c4-context.md +61 -0
- package/docs/architecture/04-bounded-contexts.md +119 -0
- package/docs/architecture/05-c4-container.md +88 -0
- package/docs/architecture/06-threat-model.md +172 -0
- package/docs/architecture/08-contracts.md +105 -0
- package/docs/architecture/MANIFESTO.md +38 -0
- package/docs/architecture/PROCESS.md +64 -0
- package/docs/architecture/README.md +37 -0
- package/docs/architecture/adr/0000-template.md +65 -0
- package/docs/architecture/adr/0001-layer-0-gate-legacy-exclusion.md +75 -0
- package/docs/architecture/adr/0002-session-view-descriptor.md +57 -0
- package/docs/architecture/adr/0003-sandbox-runtime-tier-ladder.md +63 -0
- package/docs/architecture/adr/0004-operator-authentication-substrate.md +63 -0
- package/docs/architecture/adr/0005-egress-credential-delivery-envoy-sds.md +62 -0
- package/docs/architecture/adr/0006-egress-forward-proxy-substrate.md +65 -0
- package/docs/architecture/adr/0007-egress-auth-mechanism.md +72 -0
- package/docs/architecture/adr/0008-session-egress-attribution.md +59 -0
- package/docs/architecture/adr/0009-audit-pipeline-pluggable-by-contract.md +76 -0
- package/docs/architecture/adr/0010-storage-backend-pluggable-adapter.md +60 -0
- package/docs/architecture/adr/0011-storage-egress-lane.md +67 -0
- package/docs/architecture/adr/0012-implementation-language.md +67 -0
- package/docs/architecture/adr/0020-sandbox-image-provisioning.md +82 -0
- package/docs/architecture/adr/README.md +53 -0
- package/docs/architecture/compliance/.gitkeep +0 -0
- package/docs/architecture/components/00-overview.md +42 -0
- package/docs/architecture/components/0000-template.md +50 -0
- package/docs/architecture/components/01-mcp-gateway.md +80 -0
- package/docs/architecture/components/02-control-operator-api.md +80 -0
- package/docs/architecture/components/04-storage-broker.md +104 -0
- package/docs/architecture/components/05-session-sandbox.md +93 -0
- package/docs/architecture/components/06-egress-trust-edge.md +95 -0
- package/docs/architecture/components/07-audit-pipeline.md +110 -0
- package/docs/architecture/diagrams/.gitkeep +0 -0
- package/docs/architecture/diagrams/02-trust-boundaries.mmd +111 -0
- package/docs/architecture/diagrams/06-threat-model.mmd +41 -0
- package/docs/architecture/diagrams/08-contracts.mmd +47 -0
- package/docs/architecture/diagrams/c4-container.mmd +59 -0
- package/docs/architecture/diagrams/c4-context.mmd +46 -0
- package/docs/architecture/glossary.md +172 -0
- package/docs/architecture/manifesto/.gitkeep +0 -0
- package/docs/architecture/manifesto/01-audience-and-buyer.md +57 -0
- package/docs/architecture/manifesto/02-nfrs.md +325 -0
- package/docs/architecture/manifesto/03-non-negotiables.md +35 -0
- package/docs/architecture/manifesto/04-non-goals.md +23 -0
- package/docs/architecture/manifesto/05-licensing-posture.md +61 -0
- package/docs/architecture/manifesto/06-starter-mode-policy.md +49 -0
- package/docs/architecture/manifesto/07-governance.md +60 -0
- package/docs/architecture/primitives-backlog.md +51 -0
- package/docs/architecture.svg +117 -0
- package/docs/claude-code-gateway.md +173 -0
- package/docs/cli-config-templates.md +240 -0
- package/docs/data-flow.svg +72 -0
- package/docs/demo-landing-page.gif +0 -0
- package/docs/demo-qwen-trending.gif +0 -0
- package/docs/dynamic-skills.svg +77 -0
- package/docs/file-flow.svg +126 -0
- package/docs/future-architecture/README.md +152 -0
- package/docs/future-architecture/adr/0001-control-plane-language-go.md +80 -0
- package/docs/future-architecture/adr/0002-guest-agent-language-go.md +84 -0
- package/docs/future-architecture/adr/0003-docker-poc-first-then-k8s.md +37 -0
- package/docs/future-architecture/adr/0004-pluggable-runtime-via-runtimeclass.md +34 -0
- package/docs/future-architecture/adr/0005-mcp-as-control-plane-gateway.md +34 -0
- package/docs/future-architecture/adr/0006-no-agpl-no-bsl-dependencies.md +41 -0
- package/docs/future-architecture/adr/0007-superseded-by-future-architecture.md +37 -0
- package/docs/future-architecture/adr/0008-internal-grpc-external-rest-mcp.md +106 -0
- package/docs/future-architecture/adr/0009-external-protocol-dialects.md +94 -0
- package/docs/future-architecture/adr/0010-lambda-as-inspiration-not-runtime.md +86 -0
- package/docs/future-architecture/adr/0011-kata-as-first-class-dind-runtime.md +84 -0
- package/docs/future-architecture/antipatterns.md +552 -0
- package/docs/future-architecture/architecture/01-layers.md +109 -0
- package/docs/future-architecture/architecture/02-layer4-control-plane.md +122 -0
- package/docs/future-architecture/architecture/03-layer3-providers.md +174 -0
- package/docs/future-architecture/architecture/04-layer2-runtimes.md +114 -0
- package/docs/future-architecture/architecture/04b-credential-broker.md +153 -0
- package/docs/future-architecture/architecture/05-layer1-guest-agent.md +138 -0
- package/docs/future-architecture/architecture/06-storage.md +134 -0
- package/docs/future-architecture/architecture/07-security.md +194 -0
- package/docs/future-architecture/architecture/08-networking.md +149 -0
- package/docs/future-architecture/architecture/09-templates.md +122 -0
- package/docs/future-architecture/architecture/10-observability.md +121 -0
- package/docs/future-architecture/design-notes.md +72 -0
- package/docs/future-architecture/gaps.md +281 -0
- package/docs/future-architecture/phase-template.md +123 -0
- package/docs/future-architecture/references.md +225 -0
- package/docs/future-architecture/research/01-kata-containers.md +100 -0
- package/docs/future-architecture/research/02-e2b-infra.md +133 -0
- package/docs/future-architecture/research/03-coder.md +115 -0
- package/docs/future-architecture/research/04-cloud-hypervisor.md +99 -0
- package/docs/future-architecture/research/05-firecracker.md +114 -0
- package/docs/future-architecture/research/06-agent-sandbox.md +142 -0
- package/docs/future-architecture/research/07-chromedp.md +78 -0
- package/docs/future-architecture/research/08-microsandbox.md +78 -0
- package/docs/future-architecture/research/09-agentbox.md +135 -0
- package/docs/future-architecture/research/10-sysbox.md +100 -0
- package/docs/future-architecture/research/11-firecracker-containerd.md +93 -0
- package/docs/future-architecture/research/12-docker-socket-proxy.md +59 -0
- package/docs/future-architecture/research/14-e2b-desktop-and-surf.md +107 -0
- package/docs/future-architecture/research/18-open-webui-terminals-observed.md +135 -0
- package/docs/future-architecture/research/bank-buyer.md +96 -0
- package/docs/future-architecture/research/enthusiast-audience.md +106 -0
- package/docs/future-architecture/research/proof-uipath-anthropic-2026-05.md +76 -0
- package/docs/future-architecture/research/widemoat-thesis-advisor.md +124 -0
- package/docs/future-architecture/roadmap.md +438 -0
- package/docs/kata-runtime.md +267 -0
- package/docs/kubernetes.md +86 -0
- package/docs/logo.png +0 -0
- package/docs/multi-cli.md +161 -0
- package/docs/openwebui-filter.md +134 -0
- package/docs/roadmap/implementation-roadmap.md +104 -0
- package/docs/sandbox-contents.svg +229 -0
- package/docs/screenshots/01-create-document.png +0 -0
- package/docs/screenshots/02-file-preview.png +0 -0
- package/docs/screenshots/03-browser-viewer.png +0 -0
- package/docs/screenshots/04-sub-agent-terminal.png +0 -0
- package/docs/screenshots/05-chat-overview.png +0 -0
- package/docs/screenshots/06-sub-agent-dashboard.png +0 -0
- package/docs/screenshots/07-frontend-design-skill.png +0 -0
- package/docs/screenshots/08-pptx-skill.png +0 -0
- package/docs/screenshots/09-skill-creator.png +0 -0
- package/docs/screenshots/10-data-chart.png +0 -0
- package/docs/shared-browser.svg +102 -0
- package/docs/system-prompt.md +113 -0
- package/docs/terminal-flow.svg +69 -0
- package/examples/helm/README.md +20 -0
- package/examples/helm/standalone/values.yaml +49 -0
- package/examples/helm/with-open-webui/README.md +99 -0
- package/examples/helm/with-open-webui/values-computer-use.yaml +32 -0
- package/examples/helm/with-open-webui/values-open-webui.yaml +67 -0
- package/fonts/NotoEmoji-Regular.ttf +0 -0
- package/helm/computer-use-server/.helmignore +17 -0
- package/helm/computer-use-server/Chart.yaml +32 -0
- package/helm/computer-use-server/README.md +211 -0
- package/helm/computer-use-server/templates/NOTES.txt +66 -0
- package/helm/computer-use-server/templates/_helpers.tpl +115 -0
- package/helm/computer-use-server/templates/configmap-dind-init.yaml +82 -0
- package/helm/computer-use-server/templates/configmap.yaml +18 -0
- package/helm/computer-use-server/templates/deployment.yaml +248 -0
- package/helm/computer-use-server/templates/ingress.yaml +38 -0
- package/helm/computer-use-server/templates/networkpolicy.yaml +50 -0
- package/helm/computer-use-server/templates/pdb.yaml +16 -0
- package/helm/computer-use-server/templates/pvc-data.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-skills-cache.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-user-data.yaml +20 -0
- package/helm/computer-use-server/templates/pvc-var-lib-docker.yaml +27 -0
- package/helm/computer-use-server/templates/secret.yaml +23 -0
- package/helm/computer-use-server/templates/service.yaml +22 -0
- package/helm/computer-use-server/templates/serviceaccount.yaml +15 -0
- package/helm/computer-use-server/templates/tests/test-health.yaml +23 -0
- package/helm/computer-use-server/values.schema.json +183 -0
- package/helm/computer-use-server/values.yaml +297 -0
- package/lychee.toml +36 -0
- package/openwebui/Dockerfile +52 -0
- package/openwebui/README.md +38 -0
- package/openwebui/functions/README.md +48 -0
- package/openwebui/functions/computer_link_filter.py +487 -0
- package/openwebui/init.sh +305 -0
- package/openwebui/patches/README.md +44 -0
- package/openwebui/patches/fix_artifacts_auto_show.py +441 -0
- package/openwebui/patches/fix_attached_files_position.py +87 -0
- package/openwebui/patches/fix_large_tool_args.py +156 -0
- package/openwebui/patches/fix_large_tool_results.py +289 -0
- package/openwebui/patches/fix_preview_url_detection.py +230 -0
- package/openwebui/patches/fix_skip_embedding_chat_files.py +229 -0
- package/openwebui/patches/fix_skip_rag_files_native_fc.py +100 -0
- package/openwebui/patches/fix_tool_loop_errors.py +510 -0
- package/package.json +39 -0
- package/requirements.txt +112 -0
- package/scripts/check-config.sh +141 -0
- package/scripts/docs-lint/ai-slop-detector.sh +202 -0
- package/scripts/docs-lint/architecture-tree-whitelist.sh +131 -0
- package/scripts/docs-lint/ascii-diagram-detector.sh +58 -0
- package/scripts/docs-lint/front-matter-validator.sh +97 -0
- package/scripts/docs-lint/gitignored-ref-detector.sh +122 -0
- package/scripts/docs-lint/identity-email-detector.sh +48 -0
- package/scripts/docs-lint/test-linters.sh +354 -0
- package/scripts/docs-lint/wc-budget.sh +61 -0
- package/scripts/githooks/pre-push +75 -0
- package/server.json +13 -0
- package/settings-wrapper/Dockerfile +9 -0
- package/settings-wrapper/README.md +119 -0
- package/settings-wrapper/app.py +113 -0
- package/settings-wrapper/requirements.txt +2 -0
- package/settings-wrapper/skills.json +25 -0
- package/skills/README.md +46 -0
- package/skills/examples/algorithmic-art/SKILL.md +405 -0
- package/skills/examples/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/examples/algorithmic-art/templates/viewer.html +601 -0
- package/skills/examples/artifacts-builder/SKILL.md +74 -0
- package/skills/examples/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/examples/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/examples/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/examples/canvas-design/LICENSE.txt +202 -0
- package/skills/examples/canvas-design/SKILL.md +130 -0
- package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/examples/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/examples/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/examples/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/examples/copy-editing/SKILL.md +447 -0
- package/skills/examples/copy-editing/evals/evals.json +89 -0
- package/skills/examples/copy-editing/references/plain-english-alternatives.md +394 -0
- package/skills/examples/internal-comms/LICENSE.txt +202 -0
- package/skills/examples/internal-comms/SKILL.md +32 -0
- package/skills/examples/internal-comms/examples/3p-updates.md +47 -0
- package/skills/examples/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/examples/internal-comms/examples/faq-answers.md +30 -0
- package/skills/examples/internal-comms/examples/general-comms.md +16 -0
- package/skills/examples/mcp-builder/SKILL.md +328 -0
- package/skills/examples/mcp-builder/reference/evaluation.md +602 -0
- package/skills/examples/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/skills/examples/mcp-builder/reference/node_mcp_server.md +916 -0
- package/skills/examples/mcp-builder/reference/python_mcp_server.md +752 -0
- package/skills/examples/mcp-builder/scripts/connections.py +151 -0
- package/skills/examples/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/examples/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/examples/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/examples/product-marketing-context/SKILL.md +241 -0
- package/skills/examples/product-marketing-context/evals/evals.json +85 -0
- package/skills/examples/single-cell-rna-qc/SKILL.md +175 -0
- package/skills/examples/single-cell-rna-qc/references/scverse_qc_guidelines.md +186 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_analysis.py +232 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_core.py +233 -0
- package/skills/examples/single-cell-rna-qc/scripts/qc_plotting.py +235 -0
- package/skills/examples/skill-creator/SKILL.md +355 -0
- package/skills/examples/skill-creator/references/output-patterns.md +82 -0
- package/skills/examples/skill-creator/references/workflows.md +28 -0
- package/skills/examples/skill-creator/scripts/init_skill.py +303 -0
- package/skills/examples/skill-creator/scripts/package_skill.py +110 -0
- package/skills/examples/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/examples/slack-gif-creator/SKILL.md +254 -0
- package/skills/examples/slack-gif-creator/core/easing.py +234 -0
- package/skills/examples/slack-gif-creator/core/frame_composer.py +176 -0
- package/skills/examples/slack-gif-creator/core/gif_builder.py +269 -0
- package/skills/examples/slack-gif-creator/core/validators.py +136 -0
- package/skills/examples/slack-gif-creator/requirements.txt +4 -0
- package/skills/examples/social-content/SKILL.md +278 -0
- package/skills/examples/social-content/evals/evals.json +92 -0
- package/skills/examples/social-content/references/platforms.md +170 -0
- package/skills/examples/social-content/references/post-templates.md +177 -0
- package/skills/examples/social-content/references/reverse-engineering.md +195 -0
- package/skills/examples/theme-factory/SKILL.md +59 -0
- package/skills/examples/theme-factory/theme-showcase.pdf +0 -0
- package/skills/examples/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/examples/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/examples/theme-factory/themes/desert-rose.md +19 -0
- package/skills/examples/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/examples/theme-factory/themes/golden-hour.md +19 -0
- package/skills/examples/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/examples/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/examples/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/examples/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/examples/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/examples/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/examples/web-artifacts-builder/SKILL.md +74 -0
- package/skills/examples/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/examples/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/examples/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/examples/writing-skills/SKILL.md +655 -0
- package/skills/examples/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/examples/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/examples/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/examples/writing-skills/persuasion-principles.md +187 -0
- package/skills/examples/writing-skills/render-graphs.js +168 -0
- package/skills/examples/writing-skills/testing-skills-with-subagents.md +384 -0
- package/skills/public/describe-image/SKILL.md +105 -0
- package/skills/public/describe-image/scripts/describe.py +389 -0
- package/skills/public/doc-coauthoring/SKILL.md +375 -0
- package/skills/public/docx/LICENSE.txt +30 -0
- package/skills/public/docx/SKILL.md +199 -0
- package/skills/public/docx/docx-js.md +350 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/public/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/public/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/public/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/public/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/public/docx/ooxml/scripts/pack.py +159 -0
- package/skills/public/docx/ooxml/scripts/unpack.py +29 -0
- package/skills/public/docx/ooxml/scripts/validate.py +69 -0
- package/skills/public/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/public/docx/ooxml/scripts/validation/base.py +951 -0
- package/skills/public/docx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/public/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/public/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/public/docx/ooxml.md +632 -0
- package/skills/public/docx/scripts/__init__.py +1 -0
- package/skills/public/docx/scripts/document.py +1292 -0
- package/skills/public/docx/scripts/templates/comments.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/public/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/public/docx/scripts/templates/people.xml +3 -0
- package/skills/public/docx/scripts/utilities.py +374 -0
- package/skills/public/file-reading/LICENSE.txt +30 -0
- package/skills/public/file-reading/SKILL.md +350 -0
- package/skills/public/frontend-design/LICENSE.txt +177 -0
- package/skills/public/frontend-design/SKILL.md +42 -0
- package/skills/public/gitlab-explorer/SKILL.md +174 -0
- package/skills/public/gitlab-explorer/references/git-commands.md +323 -0
- package/skills/public/gitlab-explorer/references/glab-commands.md +282 -0
- package/skills/public/gitlab-explorer/scripts/check_gitlab_auth.sh +109 -0
- package/skills/public/pdf/FORMS.md +205 -0
- package/skills/public/pdf/REFERENCE.md +612 -0
- package/skills/public/pdf/SKILL.md +364 -0
- package/skills/public/pdf/scripts/check_bounding_boxes.py +70 -0
- package/skills/public/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/skills/public/pdf/scripts/check_fillable_fields.py +12 -0
- package/skills/public/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/skills/public/pdf/scripts/create_validation_image.py +41 -0
- package/skills/public/pdf/scripts/extract_form_field_info.py +152 -0
- package/skills/public/pdf/scripts/fill_fillable_fields.py +114 -0
- package/skills/public/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/skills/public/pdf-reading/LICENSE.txt +30 -0
- package/skills/public/pdf-reading/REFERENCE.md +196 -0
- package/skills/public/pdf-reading/SKILL.md +305 -0
- package/skills/public/playwright-cli/SKILL.md +278 -0
- package/skills/public/playwright-cli/references/request-mocking.md +87 -0
- package/skills/public/playwright-cli/references/running-code.md +232 -0
- package/skills/public/playwright-cli/references/session-management.md +169 -0
- package/skills/public/playwright-cli/references/storage-state.md +275 -0
- package/skills/public/playwright-cli/references/test-generation.md +88 -0
- package/skills/public/playwright-cli/references/tracing.md +139 -0
- package/skills/public/playwright-cli/references/video-recording.md +43 -0
- package/skills/public/pptx/LICENSE.txt +30 -0
- package/skills/public/pptx/SKILL.md +484 -0
- package/skills/public/pptx/css.md +335 -0
- package/skills/public/pptx/html2pptx.md +893 -0
- package/skills/public/pptx/html2pptx.tgz +0 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/public/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/public/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/public/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/public/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/public/pptx/ooxml/scripts/pack.py +159 -0
- package/skills/public/pptx/ooxml/scripts/unpack.py +29 -0
- package/skills/public/pptx/ooxml/scripts/validate.py +69 -0
- package/skills/public/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/public/pptx/ooxml/scripts/validation/base.py +951 -0
- package/skills/public/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/public/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/public/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/public/pptx/ooxml.md +427 -0
- package/skills/public/pptx/scripts/inventory.py +1020 -0
- package/skills/public/pptx/scripts/rearrange.py +231 -0
- package/skills/public/pptx/scripts/replace.py +385 -0
- package/skills/public/pptx/scripts/thumbnail.py +450 -0
- package/skills/public/skill-creator/SKILL.md +356 -0
- package/skills/public/skill-creator/references/output-patterns.md +82 -0
- package/skills/public/skill-creator/references/workflows.md +28 -0
- package/skills/public/skill-creator/scripts/init_skill.py +303 -0
- package/skills/public/skill-creator/scripts/package_skill.py +110 -0
- package/skills/public/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/public/sub-agent/SKILL.md +186 -0
- package/skills/public/sub-agent/references/security-review.md +153 -0
- package/skills/public/sub-agent/references/usage.md +207 -0
- package/skills/public/sub-agent/scripts/list_subagent_models.sh +22 -0
- package/skills/public/test-driven-development/SKILL.md +371 -0
- package/skills/public/test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/public/webapp-testing/LICENSE.txt +202 -0
- package/skills/public/webapp-testing/SKILL.md +96 -0
- package/skills/public/webapp-testing/examples/console_logging.py +35 -0
- package/skills/public/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/public/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/public/webapp-testing/scripts/with_server.py +106 -0
- package/skills/public/xlsx/LICENSE.txt +30 -0
- package/skills/public/xlsx/SKILL.md +316 -0
- package/skills/public/xlsx/preview_data.py +93 -0
- package/skills/public/xlsx/recalc.py +178 -0
- package/tests/README.md +42 -0
- package/tests/fixtures/cli/claude_v0.9.2.0_argv.json +46 -0
- package/tests/fixtures/cli/claude_v0.9.2.0_stdout.json +32 -0
- package/tests/fixtures/cli/codex_run.jsonl +4 -0
- package/tests/fixtures/cli/opencode_run.jsonl +6 -0
- package/tests/integration/README.md +56 -0
- package/tests/integration/conftest.py +280 -0
- package/tests/integration/pytest.ini +13 -0
- package/tests/integration/test_mcp_auth.py +85 -0
- package/tests/integration/test_mcp_tools.py +101 -0
- package/tests/integration/test_workspace_lifecycle.py +125 -0
- package/tests/orchestrator/mock_llm_server.py +343 -0
- package/tests/orchestrator/test_cli_adapters.py +566 -0
- package/tests/orchestrator/test_cli_adapters_live.py +527 -0
- package/tests/orchestrator/test_cli_runtime.py +451 -0
- package/tests/orchestrator/test_docker_manager.py +302 -0
- package/tests/orchestrator/test_dynamic_instructions.py +69 -0
- package/tests/orchestrator/test_mcp_resources.py +140 -0
- package/tests/orchestrator/test_mcp_tools.py +224 -0
- package/tests/orchestrator/test_passthrough_isolation.py +201 -0
- package/tests/orchestrator/test_readme_in_container.py +76 -0
- package/tests/orchestrator/test_render_cache.py +84 -0
- package/tests/orchestrator/test_runtime_cli_endpoint.py +108 -0
- package/tests/orchestrator/test_single_user_mode.py +212 -0
- package/tests/orchestrator/test_startup_warnings.py +123 -0
- package/tests/orchestrator/test_sub_agent_dispatch.py +327 -0
- package/tests/orchestrator/test_subagent_claude_compat.py +367 -0
- package/tests/orchestrator/test_system_prompt_endpoint.py +191 -0
- package/tests/orchestrator/test_tool_descriptions.py +52 -0
- package/tests/orchestrator/test_view_image.py +201 -0
- package/tests/patches/conftest.py +30 -0
- package/tests/patches/fixtures/__init__.py +10 -0
- package/tests/patches/fixtures/middleware_v0.9.1.py +5057 -0
- package/tests/patches/fixtures/middleware_v0.9.2.py +5120 -0
- package/tests/patches/fixtures/retrieval_v0.9.1.py +2684 -0
- package/tests/patches/fixtures/retrieval_v0.9.2.py +2700 -0
- package/tests/patches/test_fix_attached_files_position.py +118 -0
- package/tests/patches/test_fix_large_tool_args.py +130 -0
- package/tests/patches/test_fix_large_tool_results.py +531 -0
- package/tests/patches/test_fix_skip_embedding_chat_files.py +160 -0
- package/tests/patches/test_fix_skip_rag_files_native_fc.py +120 -0
- package/tests/patches/test_fix_tool_loop_errors.py +128 -0
- package/tests/security/test_path_traversal_app.py +132 -0
- package/tests/security/test_path_traversal_docker.py +36 -0
- package/tests/security/test_path_traversal_settings.py +87 -0
- package/tests/security/test_safe_path_util.py +166 -0
- package/tests/security/test_xss_preview.py +46 -0
- package/tests/test-default-model-resolution.py +136 -0
- package/tests/test-docker-image.sh +358 -0
- package/tests/test-list-subagent-models.sh +421 -0
- package/tests/test-mcp-endpoint-live.sh +92 -0
- package/tests/test-mcp-native-surface.sh +213 -0
- package/tests/test-no-cyrillic.sh +135 -0
- package/tests/test-opencode-error-mapping.py +130 -0
- package/tests/test-pr88-skills.sh +305 -0
- package/tests/test-project-structure.sh +202 -0
- package/tests/test-single-user-mode.sh +269 -0
- package/tests/test-skill-no-hardcoded-models.sh +65 -0
- package/tests/test-subagent-cli-surface.py +137 -0
- package/tests/test-subagent-runtime.sh +109 -0
- package/tests/test_codex_toml_converter.py +204 -0
- package/tests/test_default_resolver_no_legacy_global.py +159 -0
- package/tests/test_filter.py +648 -0
- package/tests/test_init_sh_unchanged.sh +49 -0
- package/tests/test_opencode_alias_map_drop.py +144 -0
- package/tests/test_requirements.py +91 -0
- package/tests/test_subagent_docstring.py +193 -0
- package/tests/test_tools.py +34 -0
- package/vendor/extract-text/README.md +46 -0
- package/vendor/extract-text/extract-text +0 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
# SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
2
|
+
# Copyright (c) 2025 Open Computer Use Contributors
|
|
3
|
+
"""
|
|
4
|
+
title: Computer Use Filter
|
|
5
|
+
author: Open Computer Use Contributors
|
|
6
|
+
version: 4.1.0
|
|
7
|
+
required_open_webui_version: 0.5.17
|
|
8
|
+
description: HTTP-fetches Computer Use system prompt from orchestrator, with LRU cache and stale-cache fallback. outlet() decorates assistant messages with a preview button and/or archive button based on PREVIEW_MODE and ARCHIVE_BUTTON Valves. The inline-iframe artifact is no longer emitted — the frontend fix_preview_url_detection patch promotes the preview URL into an artifact on its own.
|
|
9
|
+
|
|
10
|
+
This filter works in conjunction with Computer Use Tools (computer_use_tools.py).
|
|
11
|
+
|
|
12
|
+
FUNCTIONALITY:
|
|
13
|
+
- inlet(): When tool "ai_computer_use" is active and chat_id is present, fetches the
|
|
14
|
+
fully-baked system prompt from the orchestrator's /system-prompt endpoint (server
|
|
15
|
+
substitutes {file_base_url}, {archive_url}, {chat_id} and assembles <available_skills>)
|
|
16
|
+
and injects it into the system message. Cache: 5-minute TTL, max 100 entries,
|
|
17
|
+
O(1) LRU eviction. On fetch failure: serve stale cache if present; else skip injection.
|
|
18
|
+
The server returns its public URL in the X-Public-Base-URL response header; inlet()
|
|
19
|
+
caches it alongside the prompt so outlet() can decorate with browser-facing links.
|
|
20
|
+
- outlet(): Decorates assistant messages whose content contains either a file URL for
|
|
21
|
+
the current chat_id OR a <details type="tool_calls"> block that references a browser
|
|
22
|
+
tool (playwright, chromium, screenshot, start-browser). Decoration is driven by two
|
|
23
|
+
Valves: PREVIEW_MODE ("button" | "off", default "button") and
|
|
24
|
+
ARCHIVE_BUTTON ("on" | "off", default "on"). All decorations are idempotent (substring
|
|
25
|
+
guarded) and scoped to the current chat_id. Archive button also requires a file URL.
|
|
26
|
+
|
|
27
|
+
CHANGELOG (v4.1.0) — BREAKING:
|
|
28
|
+
- Removed PREVIEW_MODE="artifact" / "both". outlet() no longer emits a fenced
|
|
29
|
+
```html <iframe src="..."> block. The frontend fix_preview_url_detection patch
|
|
30
|
+
already promotes any /preview/ URL in message text into an inline artifact, so
|
|
31
|
+
the extra html block was redundant and, worse, suppressed the patch (its guard
|
|
32
|
+
`!htmlGroups.some(o=>o.html)` fails when the block is present, leaving the
|
|
33
|
+
iframe rendered as a raw code fence in chat). Only "button" and "off" remain;
|
|
34
|
+
"button" is the new default. Matches the internal prod behaviour (v3.8.0).
|
|
35
|
+
|
|
36
|
+
CHANGELOG (v4.0.0) — BREAKING:
|
|
37
|
+
- Removed FILE_SERVER_URL and SYSTEM_PROMPT_URL Valves. Replaced with a single
|
|
38
|
+
ORCHESTRATOR_URL Valve (internal URL, default "http://computer-use-server:8081").
|
|
39
|
+
The public URL is now owned by the server (PUBLIC_BASE_URL env) and delivered to
|
|
40
|
+
the filter via the X-Public-Base-URL response header on /system-prompt, so the
|
|
41
|
+
filter never needs to know the browser-facing URL.
|
|
42
|
+
- _fetch_system_prompt() signature changed: now returns tuple[public_url, prompt]
|
|
43
|
+
instead of just prompt. outlet() reads the cached public_url when decorating.
|
|
44
|
+
- Valves seeded via Open WebUI admin UI or init.sh with the new ORCHESTRATOR_URL
|
|
45
|
+
name; saved FILE_SERVER_URL / SYSTEM_PROMPT_URL values from earlier versions are
|
|
46
|
+
ignored and the default is used instead — re-seed after upgrade.
|
|
47
|
+
|
|
48
|
+
CHANGELOG (v3.4.0):
|
|
49
|
+
- Removed legacy v3.2.0 boolean Valves (ENABLE_PREVIEW_ARTIFACT,
|
|
50
|
+
ENABLE_PREVIEW_BUTTON, ENABLE_ARCHIVE_BUTTON) and their @model_validator bridge.
|
|
51
|
+
|
|
52
|
+
CHANGELOG (v3.3.0):
|
|
53
|
+
- Collapsed three boolean preview/archive Valves into two Literal Valves
|
|
54
|
+
(PREVIEW_MODE, ARCHIVE_BUTTON).
|
|
55
|
+
|
|
56
|
+
CHANGELOG (v3.2.0):
|
|
57
|
+
- Added ENABLE_PREVIEW_ARTIFACT Valve — outlet() emits an inline iframe artifact.
|
|
58
|
+
- Added ENABLE_PREVIEW_BUTTON Valve — opt-in markdown button fallback.
|
|
59
|
+
|
|
60
|
+
CHANGELOG (v3.1.0):
|
|
61
|
+
- Removed hardcoded system prompt; server is now the single source of truth.
|
|
62
|
+
- HTTP fetch + OrderedDict LRU cache + stale-cache fallback.
|
|
63
|
+
|
|
64
|
+
CHANGELOG (v3.0.2):
|
|
65
|
+
- Previous version with hardcoded prompt; see git history for details.
|
|
66
|
+
|
|
67
|
+
VALVES:
|
|
68
|
+
ORCHESTRATOR_URL (str, default "http://computer-use-server:8081"):
|
|
69
|
+
Internal URL of the Computer Use orchestrator — must be reachable
|
|
70
|
+
from inside the Open WebUI container (server→server fetch for
|
|
71
|
+
/system-prompt). Never appears in browser-facing URLs. The default
|
|
72
|
+
works out of the box with the reference docker-compose stack (both
|
|
73
|
+
services on the same Docker network, service DNS resolves the name).
|
|
74
|
+
For production deploys, point this at the internal hostname / k8s
|
|
75
|
+
service DNS of the orchestrator.
|
|
76
|
+
The browser-facing URL for preview/archive links is owned by the
|
|
77
|
+
server (PUBLIC_BASE_URL env) and returned via the X-Public-Base-URL
|
|
78
|
+
response header on /system-prompt.
|
|
79
|
+
INJECT_SYSTEM_PROMPT (bool, default True):
|
|
80
|
+
If False, inlet() skips system-prompt injection entirely (useful when
|
|
81
|
+
another filter owns the prompt).
|
|
82
|
+
PREVIEW_MODE (Literal["button","off"], default "button"):
|
|
83
|
+
Where the preview link appears on assistant messages.
|
|
84
|
+
- "button": markdown [{PREVIEW_BUTTON_TEXT}]({public}/preview/{chat_id}).
|
|
85
|
+
The fix_preview_url_detection frontend patch detects this URL in
|
|
86
|
+
message text and auto-opens it as an inline artifact — no fenced
|
|
87
|
+
html block needed. Works on both patched and stock Open WebUI
|
|
88
|
+
(stock renders a clickable link; patched renders inline artifact).
|
|
89
|
+
- "off": no preview link.
|
|
90
|
+
ARCHIVE_BUTTON (Literal["on","off"], default "on"):
|
|
91
|
+
Append a markdown [{ARCHIVE_BUTTON_TEXT}]({public}/files/{chat_id}/archive)
|
|
92
|
+
link to assistant messages that contain files for the current chat_id.
|
|
93
|
+
PREVIEW_BUTTON_TEXT (str, default "🖥️ Open preview"):
|
|
94
|
+
Label for the preview-button markdown link.
|
|
95
|
+
ARCHIVE_BUTTON_TEXT (str, default "📦 Download all files as archive"):
|
|
96
|
+
Label for the archive-download markdown link.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
import re
|
|
100
|
+
import time
|
|
101
|
+
import urllib.error
|
|
102
|
+
import urllib.parse
|
|
103
|
+
import urllib.request
|
|
104
|
+
from collections import OrderedDict
|
|
105
|
+
from typing import Literal, Optional
|
|
106
|
+
|
|
107
|
+
from pydantic import BaseModel, Field
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# All known Open WebUI template variables
|
|
111
|
+
# https://docs.openwebui.com/features/workspace/prompts/
|
|
112
|
+
OPENWEBUI_TEMPLATE_VARS = [
|
|
113
|
+
"CURRENT_DATE", "CURRENT_DATETIME", "CURRENT_TIME",
|
|
114
|
+
"CURRENT_TIMEZONE", "CURRENT_WEEKDAY",
|
|
115
|
+
"USER_NAME", "USER_LANGUAGE", "USER_LOCATION",
|
|
116
|
+
"CLIPBOARD",
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
# Pattern: {{ VAR }} or {{VAR}} (with/without spaces, Jinja2-style)
|
|
120
|
+
TEMPLATE_PATTERN = r"^.*\{\{\s*(?:" + "|".join(OPENWEBUI_TEMPLATE_VARS) + r")\s*\}\}.*$"
|
|
121
|
+
|
|
122
|
+
# Cache TTL and size (module-level so tests can patch them)
|
|
123
|
+
_PROMPT_TTL_SECONDS = 300
|
|
124
|
+
_PROMPT_CACHE_MAX_SIZE = 100
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _find_block_start(content: str, pos: int) -> int:
|
|
128
|
+
"""
|
|
129
|
+
Find the start of the text block containing position `pos`.
|
|
130
|
+
|
|
131
|
+
A block is delimited by an empty line (double newline) or the start of content.
|
|
132
|
+
Used to inject the Computer Use system prompt BEFORE any Open WebUI template block.
|
|
133
|
+
"""
|
|
134
|
+
boundary = content.rfind("\n\n", 0, pos)
|
|
135
|
+
return boundary + 2 if boundary != -1 else 0
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# Open WebUI renders tool invocations into assistant content as
|
|
139
|
+
# <details type="tool_calls" ... name="X" arguments="Y" result="Z" ...>.
|
|
140
|
+
# The /api/chat/completed endpoint strips raw `tool_calls` / role="tool"
|
|
141
|
+
# (Chat.svelte sends only {id, role, content, info, timestamp, usage, sources}),
|
|
142
|
+
# so content-scan is the only reliable detection path in outlet() for sessions
|
|
143
|
+
# that exercised browser tools without producing file URLs.
|
|
144
|
+
_TOOL_CALL_DETAILS_RE = re.compile(
|
|
145
|
+
r'<details\s+[^>]*type="tool_calls"[^>]*>',
|
|
146
|
+
re.IGNORECASE,
|
|
147
|
+
)
|
|
148
|
+
_NAME_ATTR_RE = re.compile(r'\bname="([^"]*)"')
|
|
149
|
+
_ARGS_ATTR_RE = re.compile(r'\barguments="([^"]*)"')
|
|
150
|
+
_BROWSER_TOOL_KEYWORDS = ("playwright", "start-browser", "chromium", "screenshot")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _extract_tool_calls_from_content(content: str) -> list[tuple[str, str]]:
|
|
154
|
+
"""Return [(name, arguments_raw), ...] from <details type="tool_calls"> tags.
|
|
155
|
+
|
|
156
|
+
Attribute values are html-escaped as delivered by Open WebUI; substring
|
|
157
|
+
keyword matching is robust to that — no need to unescape for detection.
|
|
158
|
+
"""
|
|
159
|
+
if not content:
|
|
160
|
+
return []
|
|
161
|
+
out: list[tuple[str, str]] = []
|
|
162
|
+
for m in _TOOL_CALL_DETAILS_RE.finditer(content):
|
|
163
|
+
tag = m.group(0)
|
|
164
|
+
n = _NAME_ATTR_RE.search(tag)
|
|
165
|
+
a = _ARGS_ATTR_RE.search(tag)
|
|
166
|
+
out.append((n.group(1) if n else "", a.group(1) if a else ""))
|
|
167
|
+
return out
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _content_has_browser_tool(content: str) -> bool:
|
|
171
|
+
"""True when the assistant message embeds a tool_calls details block that
|
|
172
|
+
references a browser tool (playwright, chromium, screenshot, start-browser).
|
|
173
|
+
|
|
174
|
+
Scoped to <details type="tool_calls"> tags — free text in user/assistant
|
|
175
|
+
messages is never scanned, so keyword mentions ("how does playwright work?")
|
|
176
|
+
do not trigger a false positive.
|
|
177
|
+
"""
|
|
178
|
+
for name, args in _extract_tool_calls_from_content(content):
|
|
179
|
+
blob = (name + " " + args).lower()
|
|
180
|
+
if any(kw in blob for kw in _BROWSER_TOOL_KEYWORDS):
|
|
181
|
+
return True
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class Filter:
|
|
186
|
+
class Valves(BaseModel):
|
|
187
|
+
ORCHESTRATOR_URL: str = Field(
|
|
188
|
+
default="http://computer-use-server:8081",
|
|
189
|
+
description="Internal URL of the Computer Use orchestrator. Must be reachable from inside the Open WebUI container for server→server /system-prompt fetch. NOT browser-facing — the public URL is owned by the server (PUBLIC_BASE_URL env) and returned via the X-Public-Base-URL response header. Trailing slash is tolerated.",
|
|
190
|
+
)
|
|
191
|
+
INJECT_SYSTEM_PROMPT: bool = Field(
|
|
192
|
+
default=True,
|
|
193
|
+
description="Inject Computer Use system prompt when tools are active. Turn off only if another filter owns the prompt.",
|
|
194
|
+
)
|
|
195
|
+
PREVIEW_MODE: Literal["button", "off"] = Field(
|
|
196
|
+
default="button",
|
|
197
|
+
description="Where the preview link appears on assistant messages. button=markdown link (the fix_preview_url_detection frontend patch turns it into an inline artifact on patched builds; stock Open WebUI shows it as a clickable link). off=no preview link.",
|
|
198
|
+
)
|
|
199
|
+
ARCHIVE_BUTTON: Literal["on", "off"] = Field(
|
|
200
|
+
default="on",
|
|
201
|
+
description="Append a 'Download all files as archive' link to assistant messages that contain files.",
|
|
202
|
+
)
|
|
203
|
+
PREVIEW_BUTTON_TEXT: str = Field(
|
|
204
|
+
default="🖥️ Open preview",
|
|
205
|
+
description="Text for the preview-button markdown link (used when PREVIEW_MODE is 'button').",
|
|
206
|
+
)
|
|
207
|
+
ARCHIVE_BUTTON_TEXT: str = Field(
|
|
208
|
+
default="📦 Download all files as archive",
|
|
209
|
+
description="Text for the archive-download button (when ARCHIVE_BUTTON is on).",
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def __init__(self):
|
|
213
|
+
self.valves = self.Valves()
|
|
214
|
+
# Per-(chat, user) LRU cache: (chat_id, user_email) -> (fetched_at, (public_url, prompt))
|
|
215
|
+
# - Keyed by user identity because the server bakes a user-specific <available_skills>
|
|
216
|
+
# block — sharing across users would leak skills and break correctness.
|
|
217
|
+
# - Value is a tuple so outlet() can read the public URL (from the server's
|
|
218
|
+
# X-Public-Base-URL response header) without its own URL Valve.
|
|
219
|
+
self._prompt_cache: OrderedDict[
|
|
220
|
+
tuple[str, str], tuple[float, tuple[str, str]]
|
|
221
|
+
] = OrderedDict()
|
|
222
|
+
|
|
223
|
+
def _fetch_system_prompt(
|
|
224
|
+
self, chat_id: str, user_email: str = ""
|
|
225
|
+
) -> Optional[tuple[str, str]]:
|
|
226
|
+
"""
|
|
227
|
+
Fetch system prompt from the orchestrator with per-(chat, user) caching.
|
|
228
|
+
|
|
229
|
+
Returns (public_url, prompt) on success, or the cached value on stale-cache
|
|
230
|
+
fallback if the fetch failed but a previous entry exists. Returns None when
|
|
231
|
+
the cache is cold AND the server is unreachable — caller must skip injection.
|
|
232
|
+
|
|
233
|
+
The public_url comes from the server's X-Public-Base-URL response header
|
|
234
|
+
(PUBLIC_BASE_URL env on the server). outlet() uses it to build browser-facing
|
|
235
|
+
preview/archive links. Fallback: if the header is absent (older server), the
|
|
236
|
+
ORCHESTRATOR_URL Valve is reused — only correct for bare-metal/co-located
|
|
237
|
+
deploys where internal == public.
|
|
238
|
+
"""
|
|
239
|
+
now = time.time()
|
|
240
|
+
cache_key = (chat_id, user_email)
|
|
241
|
+
cached = self._prompt_cache.get(cache_key)
|
|
242
|
+
|
|
243
|
+
# Cache hit within TTL
|
|
244
|
+
if cached and (now - cached[0]) < _PROMPT_TTL_SECONDS:
|
|
245
|
+
self._prompt_cache.move_to_end(cache_key)
|
|
246
|
+
return cached[1]
|
|
247
|
+
|
|
248
|
+
# Build URL (resolved at request time so Valves updates are honoured)
|
|
249
|
+
orchestrator = self.valves.ORCHESTRATOR_URL.rstrip("/")
|
|
250
|
+
base_url = orchestrator + "/system-prompt"
|
|
251
|
+
|
|
252
|
+
# Only http(s) is a valid orchestrator transport. Reject file://, ftp://,
|
|
253
|
+
# data://, etc. — otherwise a misconfigured Valve could read arbitrary
|
|
254
|
+
# local files through urlopen (ruff S310).
|
|
255
|
+
parsed = urllib.parse.urlparse(base_url)
|
|
256
|
+
if parsed.scheme not in ("http", "https"):
|
|
257
|
+
print(
|
|
258
|
+
f"[ComputerUseFilter] Unsupported orchestrator URL scheme: "
|
|
259
|
+
f"{parsed.scheme!r} (expected http/https)"
|
|
260
|
+
)
|
|
261
|
+
return cached[1] if cached else None
|
|
262
|
+
|
|
263
|
+
params = {}
|
|
264
|
+
if chat_id:
|
|
265
|
+
params["chat_id"] = chat_id
|
|
266
|
+
if user_email:
|
|
267
|
+
params["user_email"] = user_email
|
|
268
|
+
url = base_url + ("?" + urllib.parse.urlencode(params) if params else "")
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
req = urllib.request.Request(url, method="GET")
|
|
272
|
+
req.add_header("Accept", "text/plain")
|
|
273
|
+
with urllib.request.urlopen(req, timeout=10) as resp: # noqa: S310 — scheme validated above
|
|
274
|
+
prompt = resp.read().decode("utf-8")
|
|
275
|
+
# X-Public-Base-URL header tells outlet() which URL to put in
|
|
276
|
+
# browser-facing iframe/archive links. When the header is
|
|
277
|
+
# missing (older server), fall back to the internal Valve —
|
|
278
|
+
# this is only correct when ORCHESTRATOR_URL == public URL
|
|
279
|
+
# (bare-metal co-located deploy).
|
|
280
|
+
public_url = (
|
|
281
|
+
resp.headers.get("X-Public-Base-URL") or orchestrator
|
|
282
|
+
)
|
|
283
|
+
public_url = public_url.rstrip("/")
|
|
284
|
+
|
|
285
|
+
entry = (public_url, prompt)
|
|
286
|
+
# Cache the ready-to-use (public_url, prompt) pair
|
|
287
|
+
self._prompt_cache[cache_key] = (now, entry)
|
|
288
|
+
self._prompt_cache.move_to_end(cache_key)
|
|
289
|
+
|
|
290
|
+
# Evict oldest entry when over capacity (O(1) with OrderedDict)
|
|
291
|
+
while len(self._prompt_cache) > _PROMPT_CACHE_MAX_SIZE:
|
|
292
|
+
self._prompt_cache.popitem(last=False)
|
|
293
|
+
|
|
294
|
+
return entry
|
|
295
|
+
|
|
296
|
+
except (urllib.error.URLError, TimeoutError, UnicodeDecodeError) as e:
|
|
297
|
+
# Narrow to real transport/decoding failures. Broader Exception
|
|
298
|
+
# would swallow configuration bugs (e.g. attribute errors on the
|
|
299
|
+
# Valves model) behind the stale-cache fallback and make them
|
|
300
|
+
# invisible (ruff BLE001).
|
|
301
|
+
print(f"[ComputerUseFilter] Failed to fetch system prompt: {e}")
|
|
302
|
+
# Stale-cache fallback (any age) when available
|
|
303
|
+
if cached:
|
|
304
|
+
return cached[1]
|
|
305
|
+
# Cold cache + server down -> caller skips injection
|
|
306
|
+
return None
|
|
307
|
+
|
|
308
|
+
def inlet(
|
|
309
|
+
self,
|
|
310
|
+
body: dict,
|
|
311
|
+
__user__: Optional[dict] = None,
|
|
312
|
+
__metadata__: Optional[dict] = None,
|
|
313
|
+
) -> dict:
|
|
314
|
+
"""Inject Computer Use system prompt BEFORE LLM processing."""
|
|
315
|
+
if not self.valves.INJECT_SYSTEM_PROMPT:
|
|
316
|
+
return body
|
|
317
|
+
|
|
318
|
+
tool_ids = body.get("tool_ids", [])
|
|
319
|
+
if "ai_computer_use" not in tool_ids:
|
|
320
|
+
return body
|
|
321
|
+
|
|
322
|
+
chat_id = __metadata__.get("chat_id") if __metadata__ else None
|
|
323
|
+
if not chat_id:
|
|
324
|
+
return body
|
|
325
|
+
|
|
326
|
+
user_email = __user__.get("email", "") if __user__ else ""
|
|
327
|
+
|
|
328
|
+
fetched = self._fetch_system_prompt(chat_id, user_email)
|
|
329
|
+
if not fetched:
|
|
330
|
+
# Cold cache + server down -> skip injection (same no-op path as missing chat_id)
|
|
331
|
+
return body
|
|
332
|
+
_public_url, system_prompt = fetched
|
|
333
|
+
|
|
334
|
+
messages = body.get("messages", [])
|
|
335
|
+
if not messages:
|
|
336
|
+
return body
|
|
337
|
+
|
|
338
|
+
# Locate existing system message
|
|
339
|
+
system_msg_idx = None
|
|
340
|
+
for idx, msg in enumerate(messages):
|
|
341
|
+
if msg.get("role") == "system":
|
|
342
|
+
system_msg_idx = idx
|
|
343
|
+
break
|
|
344
|
+
|
|
345
|
+
if system_msg_idx is not None:
|
|
346
|
+
existing_content = messages[system_msg_idx].get("content", "")
|
|
347
|
+
# Some Open WebUI flows deliver structured content (e.g. a list of
|
|
348
|
+
# multimodal parts) instead of a plain string. re.search would
|
|
349
|
+
# crash in that case — skip template detection and fall through to
|
|
350
|
+
# the append branch, which handles arbitrary existing_content via
|
|
351
|
+
# string concatenation (str() coercion there is safe for the
|
|
352
|
+
# downstream LLM which only reads strings anyway).
|
|
353
|
+
if isinstance(existing_content, str):
|
|
354
|
+
match = re.search(TEMPLATE_PATTERN, existing_content, re.MULTILINE)
|
|
355
|
+
else:
|
|
356
|
+
match = None
|
|
357
|
+
if match:
|
|
358
|
+
# Inject BEFORE the block containing the template variable
|
|
359
|
+
block_start = _find_block_start(existing_content, match.start())
|
|
360
|
+
messages[system_msg_idx]["content"] = (
|
|
361
|
+
existing_content[:block_start].rstrip()
|
|
362
|
+
+ "\n\n"
|
|
363
|
+
+ system_prompt
|
|
364
|
+
+ "\n\n"
|
|
365
|
+
+ existing_content[block_start:]
|
|
366
|
+
)
|
|
367
|
+
else:
|
|
368
|
+
# No template vars (or non-string content) -> append as plain string.
|
|
369
|
+
# When existing_content is a list of multimodal parts, coerce to
|
|
370
|
+
# str() first so the LLM still sees the Computer Use prompt; the
|
|
371
|
+
# original structured content is preserved via the repr.
|
|
372
|
+
if isinstance(existing_content, str):
|
|
373
|
+
messages[system_msg_idx]["content"] = existing_content + "\n\n" + system_prompt
|
|
374
|
+
else:
|
|
375
|
+
messages[system_msg_idx]["content"] = str(existing_content) + "\n\n" + system_prompt
|
|
376
|
+
else:
|
|
377
|
+
messages.insert(0, {"role": "system", "content": system_prompt})
|
|
378
|
+
|
|
379
|
+
body["messages"] = messages
|
|
380
|
+
return body
|
|
381
|
+
|
|
382
|
+
def outlet(
|
|
383
|
+
self,
|
|
384
|
+
body: dict,
|
|
385
|
+
__user__: Optional[dict] = None,
|
|
386
|
+
__metadata__: Optional[dict] = None,
|
|
387
|
+
) -> dict:
|
|
388
|
+
"""Append preview button and/or archive button to assistant messages with file links.
|
|
389
|
+
|
|
390
|
+
- PREVIEW_MODE="button" (default): markdown link to the preview page. The
|
|
391
|
+
frontend fix_preview_url_detection patch rewrites this URL into an inline
|
|
392
|
+
artifact; stock Open WebUI leaves it as a plain clickable link.
|
|
393
|
+
- PREVIEW_MODE="off": no preview link.
|
|
394
|
+
- ARCHIVE_BUTTON="on" (default): markdown link to the archive endpoint (only when files exist).
|
|
395
|
+
|
|
396
|
+
The public URL used in browser-facing links comes from the cached
|
|
397
|
+
X-Public-Base-URL response header captured by inlet()/_fetch_system_prompt().
|
|
398
|
+
If no cache entry exists (outlet without prior inlet, e.g. re-render of an
|
|
399
|
+
old message after server restart), decoration is skipped — broken links are
|
|
400
|
+
worse than no links.
|
|
401
|
+
|
|
402
|
+
Invariants:
|
|
403
|
+
1. Only role=="assistant" messages are touched.
|
|
404
|
+
2. Non-string content is skipped.
|
|
405
|
+
3. file_url_pattern is scoped to the current chat_id (no cross-chat decoration).
|
|
406
|
+
4. public_url is rstripped before URL construction (no //preview/ or //files/).
|
|
407
|
+
5. Substring-based idempotency — repeated outlet() calls do not duplicate.
|
|
408
|
+
"""
|
|
409
|
+
wants_button = self.valves.PREVIEW_MODE == "button"
|
|
410
|
+
wants_archive = self.valves.ARCHIVE_BUTTON == "on"
|
|
411
|
+
|
|
412
|
+
if not (wants_button or wants_archive):
|
|
413
|
+
return body
|
|
414
|
+
|
|
415
|
+
chat_id = __metadata__.get("chat_id") if __metadata__ else None
|
|
416
|
+
if not chat_id:
|
|
417
|
+
return body
|
|
418
|
+
|
|
419
|
+
# Pull the public URL from cache (populated by inlet() via the server's
|
|
420
|
+
# X-Public-Base-URL header). outlet() may run on re-renders where
|
|
421
|
+
# __user__ isn't passed, so the email-keyed cache entry inlet() wrote
|
|
422
|
+
# isn't directly reachable. Probe the exact (chat_id, user_email) and
|
|
423
|
+
# (chat_id, "") keys first, then fall back to ANY same-chat entry —
|
|
424
|
+
# outlet only needs public_url, not the prompt, so borrowing a URL
|
|
425
|
+
# from a different user's entry for the same chat is safe (public_url
|
|
426
|
+
# is chat-independent — it comes from the server's PUBLIC_BASE_URL env).
|
|
427
|
+
user_email = __user__.get("email", "") if __user__ else ""
|
|
428
|
+
cached = self._prompt_cache.get((chat_id, user_email)) or self._prompt_cache.get(
|
|
429
|
+
(chat_id, "")
|
|
430
|
+
)
|
|
431
|
+
if not cached:
|
|
432
|
+
for (cached_chat_id, _), entry in self._prompt_cache.items():
|
|
433
|
+
if cached_chat_id == chat_id:
|
|
434
|
+
cached = entry
|
|
435
|
+
break
|
|
436
|
+
if not cached:
|
|
437
|
+
# Cold-cache fallback: an Open WebUI restart wipes self._prompt_cache,
|
|
438
|
+
# and a re-render of an old assistant message can hit outlet() without
|
|
439
|
+
# inlet() running first (no new user message → no inlet pass). Rather
|
|
440
|
+
# than silently dropping preview/archive buttons, re-fetch from the
|
|
441
|
+
# orchestrator. This re-uses _fetch_system_prompt's own stale-cache
|
|
442
|
+
# fallback and url-scheme validation. Still respects the "broken links
|
|
443
|
+
# are worse than no links" invariant: if the server is unreachable AND
|
|
444
|
+
# we have no stale entry, _fetch_system_prompt returns None and we
|
|
445
|
+
# skip decoration.
|
|
446
|
+
cached_pair = self._fetch_system_prompt(chat_id, user_email)
|
|
447
|
+
if not cached_pair:
|
|
448
|
+
return body
|
|
449
|
+
public_url, _prompt = cached_pair
|
|
450
|
+
else:
|
|
451
|
+
public_url, _prompt = cached[1]
|
|
452
|
+
base = public_url.rstrip("/")
|
|
453
|
+
file_url_pattern = re.escape(base) + r"/files/" + re.escape(chat_id) + r"/[^\s\)]+"
|
|
454
|
+
preview_url = f"{base}/preview/{chat_id}"
|
|
455
|
+
archive_url = f"{base}/files/{chat_id}/archive"
|
|
456
|
+
|
|
457
|
+
for message in body.get("messages", []):
|
|
458
|
+
if message.get("role") != "assistant":
|
|
459
|
+
continue
|
|
460
|
+
content = message.get("content")
|
|
461
|
+
if not content or not isinstance(content, str):
|
|
462
|
+
continue
|
|
463
|
+
|
|
464
|
+
# Two independent triggers:
|
|
465
|
+
# 1. A file URL scoped to the current chat_id — legacy v3.2.0 path.
|
|
466
|
+
# 2. A <details type="tool_calls"> block that references a browser
|
|
467
|
+
# tool — covers sessions that exercised playwright/chromium
|
|
468
|
+
# without producing a downloadable file (e.g. pure navigation).
|
|
469
|
+
has_file_link = bool(re.search(file_url_pattern, content))
|
|
470
|
+
has_browser_tool = _content_has_browser_tool(content)
|
|
471
|
+
if not (has_file_link or has_browser_tool):
|
|
472
|
+
continue
|
|
473
|
+
|
|
474
|
+
links: list[str] = []
|
|
475
|
+
if wants_button and preview_url not in content:
|
|
476
|
+
links.append(f"[{self.valves.PREVIEW_BUTTON_TEXT}]({preview_url})")
|
|
477
|
+
# Archive download only makes sense when files actually exist for
|
|
478
|
+
# this chat — gate it on has_file_link, not on the browser-tool
|
|
479
|
+
# trigger.
|
|
480
|
+
if wants_archive and has_file_link and archive_url not in content:
|
|
481
|
+
links.append(f"[{self.valves.ARCHIVE_BUTTON_TEXT}]({archive_url})")
|
|
482
|
+
if links:
|
|
483
|
+
content += "\n\n" + "\n".join(links)
|
|
484
|
+
|
|
485
|
+
message["content"] = content
|
|
486
|
+
|
|
487
|
+
return body
|