@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,441 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
3
|
+
# Copyright (c) 2025 Open Computer Use Contributors
|
|
4
|
+
"""
|
|
5
|
+
Patch for Open WebUI 0.9.5: auto-open Artifacts panel
|
|
6
|
+
|
|
7
|
+
Problem: If an HTML code block is inside a collapsed <details>, CodeBlock is not mounted ->
|
|
8
|
+
onUpdate does not fire -> Artifacts panel does not open. Artifacts.svelte subscribe
|
|
9
|
+
does not help either because the component is not mounted while showControls=false.
|
|
10
|
+
|
|
11
|
+
Solution: Patch getContents() in Chat.svelte -- after artifactContents.set(contents),
|
|
12
|
+
if contents is non-empty, use setTimeout to set showArtifacts.set(true) and showControls.set(true).
|
|
13
|
+
setTimeout is needed because during chat initialization (loadChat/navigateHandler)
|
|
14
|
+
showControls is reset to false AFTER the reactive getContents() call.
|
|
15
|
+
A 300ms delay ensures that auto-show fires after all initialization resets.
|
|
16
|
+
|
|
17
|
+
Both components (Chat.svelte and Artifacts.svelte) are compiled into one chunk.
|
|
18
|
+
|
|
19
|
+
=== Compiled-code anchor ===
|
|
20
|
+
|
|
21
|
+
Subscribe in Artifacts.svelte:
|
|
22
|
+
STORE.subscribe(b=>{const S=b??[];
|
|
23
|
+
S.length===0?(S1.set(!1),S2.set(!1),h(f,0)):S.length>s(u).length&&h(f,S.length-1),h(u,S)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
Patch subscribe -- add auto-show to else branch:
|
|
27
|
+
Before: S.length===0?(S1.set(!1),S2.set(!1),h(f,0)):S.length>s(u).length&&h(f,S.length-1),h(u,S)
|
|
28
|
+
After: S.length===0?(S1.set(!1),S2.set(!1),h(f,0)):/* FIX_ARTIFACTS_AUTO_SHOW */(S.length>s(u).length&&h(f,S.length-1),S2.set(!0),S1.set(!0)),h(u,S)
|
|
29
|
+
|
|
30
|
+
getContents in Chat.svelte:
|
|
31
|
+
Before: STORE.set(q)},
|
|
32
|
+
After: STORE.set(q),/* FIX_ARTIFACTS_AUTO_SHOW */q.length>0&&setTimeout(()=>(S2.set(!0),S1.set(!0)),300)},
|
|
33
|
+
|
|
34
|
+
Fail-loud contract: if the anchor regex does not match any chunk, the script
|
|
35
|
+
exits with sys.exit(1) and prints "ERROR: ..." on stderr. This intentionally
|
|
36
|
+
fails the Docker build rather than producing a silently-broken image.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
import os
|
|
40
|
+
import sys
|
|
41
|
+
import glob
|
|
42
|
+
import re
|
|
43
|
+
|
|
44
|
+
BUILD_CHUNKS_DIR = "/app/build/_app/immutable/chunks"
|
|
45
|
+
|
|
46
|
+
# Idempotency marker -- injected as a JS comment at the subscribe patch site
|
|
47
|
+
# AND the getContents patch site. Presence of this marker indicates the chunk
|
|
48
|
+
# has already been patched by this script; a single substring check covers
|
|
49
|
+
# both injection sites.
|
|
50
|
+
IDEMPOTENCY_MARKER = "/* FIX_ARTIFACTS_AUTO_SHOW */"
|
|
51
|
+
|
|
52
|
+
# --- Pattern 1: Artifacts.svelte subscribe (v0.8.11-0.9.1) ---
|
|
53
|
+
# Compiled: VAR.length===0?(STORE1.set(!1),STORE2.set(!1),h(SIG,0)):VAR.length>s(SIG2).length&&h(SIG,VAR.length-1),h(SIG3,VAR)
|
|
54
|
+
# The subscribe handler: STORE.subscribe(PARAM=>{const VAR=PARAM??[];VAR.length===0?(...):...})
|
|
55
|
+
SUBSCRIBE_PATTERN = re.compile(
|
|
56
|
+
r'(\w+)\.length===0\?\((\w+)\.set\(!1\),(\w+)\.set\(!1\),(\w+)\)'
|
|
57
|
+
r':(\1)\.length>\w+\(\w+\)\.length&&(\w+)'
|
|
58
|
+
)
|
|
59
|
+
# Context: h(u,S) after the ternary (unconditional update)
|
|
60
|
+
SUBSCRIBE_CONTEXT = "h("
|
|
61
|
+
|
|
62
|
+
# --- Pattern 2: Chat.svelte getContents ---
|
|
63
|
+
# After type:"iframe" content, find STORE.set(VAR)},
|
|
64
|
+
GETCONTENTS_CONTEXT = 'type:"iframe"'
|
|
65
|
+
|
|
66
|
+
# --- Legacy already-patched marker (for chunks patched by pre-v0.9.1.0 runs) ---
|
|
67
|
+
# Subscribe patched (pre-marker builds): wraps else branch in parens with .set(!0) calls
|
|
68
|
+
SUBSCRIBE_PATCHED_MARKER = re.compile(
|
|
69
|
+
r'\.length===0\?\(\w+\.set\(!1\),\w+\.set\(!1\),.+?\):'
|
|
70
|
+
r'\(.+?\.set\(!0\),.+?\.set\(!0\)\),'
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def cache_bust_chunk(chunk_file):
|
|
75
|
+
"""Copy chunk to timestamped name and update references.
|
|
76
|
+
|
|
77
|
+
IMPORTANT: We COPY, not rename. The old file must remain because
|
|
78
|
+
browsers with immutable-cached parent modules (entry/, nodes/)
|
|
79
|
+
still reference the old filename. Both URLs must serve the patched content.
|
|
80
|
+
"""
|
|
81
|
+
import shutil
|
|
82
|
+
import hashlib
|
|
83
|
+
|
|
84
|
+
old_name = os.path.basename(chunk_file)
|
|
85
|
+
with open(chunk_file, 'rb') as _f:
|
|
86
|
+
content_hash = hashlib.md5(_f.read()).hexdigest()[:8]
|
|
87
|
+
new_name = old_name.replace('.js', f'-p{content_hash}.js')
|
|
88
|
+
new_path = os.path.join(os.path.dirname(chunk_file), new_name)
|
|
89
|
+
|
|
90
|
+
# Copy patched file to new name (keep old file for cached references)
|
|
91
|
+
shutil.copy2(chunk_file, new_path)
|
|
92
|
+
|
|
93
|
+
# Update references in nodes/, entry/, and chunks/ to point to new name
|
|
94
|
+
# New browser sessions will load the timestamped version
|
|
95
|
+
base_dir = os.path.dirname(os.path.dirname(chunk_file)) # _app/immutable
|
|
96
|
+
updated = 0
|
|
97
|
+
for subdir in ['nodes', 'entry', 'chunks']:
|
|
98
|
+
search_dir = os.path.join(base_dir, subdir)
|
|
99
|
+
if not os.path.isdir(search_dir):
|
|
100
|
+
continue
|
|
101
|
+
for fn in os.listdir(search_dir):
|
|
102
|
+
if not fn.endswith('.js'):
|
|
103
|
+
continue
|
|
104
|
+
fpath = os.path.join(search_dir, fn)
|
|
105
|
+
with open(fpath, 'r', encoding='utf-8') as f:
|
|
106
|
+
content = f.read()
|
|
107
|
+
if old_name in content:
|
|
108
|
+
content = content.replace(old_name, new_name)
|
|
109
|
+
with open(fpath, 'w', encoding='utf-8') as f:
|
|
110
|
+
f.write(content)
|
|
111
|
+
updated += 1
|
|
112
|
+
|
|
113
|
+
print(f" Cache bust: {old_name} -> {new_name} ({updated} files updated)")
|
|
114
|
+
print(f" Old file kept: {old_name} (for cached browser references)")
|
|
115
|
+
return new_path
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def find_chunk_file():
|
|
119
|
+
"""Find JS chunk containing both Artifacts subscribe and getContents patterns.
|
|
120
|
+
|
|
121
|
+
Detection: chunk must contain BOTH:
|
|
122
|
+
- 'showArtifacts' or the subscribe hide pattern (STORE.set(!1),STORE.set(!1))
|
|
123
|
+
- 'type:"iframe"' (getContents context)
|
|
124
|
+
|
|
125
|
+
Also recognise already-patched chunks (carrying IDEMPOTENCY_MARKER) so the
|
|
126
|
+
idempotent early-exit in apply_patch() can fire.
|
|
127
|
+
"""
|
|
128
|
+
if not os.path.isdir(BUILD_CHUNKS_DIR):
|
|
129
|
+
print(f"ERROR: Directory not found: {BUILD_CHUNKS_DIR}", file=sys.stderr)
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
for filepath in sorted(glob.glob(os.path.join(BUILD_CHUNKS_DIR, "*.js"))):
|
|
133
|
+
if filepath.endswith(".map"):
|
|
134
|
+
continue
|
|
135
|
+
try:
|
|
136
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
137
|
+
content = f.read()
|
|
138
|
+
# Already-patched chunk (idempotent path)
|
|
139
|
+
if IDEMPOTENCY_MARKER in content and GETCONTENTS_CONTEXT in content:
|
|
140
|
+
return filepath
|
|
141
|
+
has_subscribe = _find_subscribe_pattern(content) is not None
|
|
142
|
+
has_getcontents = GETCONTENTS_CONTEXT in content
|
|
143
|
+
if has_subscribe and has_getcontents:
|
|
144
|
+
return filepath
|
|
145
|
+
except Exception as e:
|
|
146
|
+
print(f" Warning: Could not read {filepath}: {e}")
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
return None
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _find_subscribe_pattern(content):
|
|
153
|
+
"""Find the subscribe hide pattern in Artifacts.svelte.
|
|
154
|
+
|
|
155
|
+
Pattern:
|
|
156
|
+
VAR.length===0?(STORE1.set(!1),STORE2.set(!1),h(SIG1,0)):VAR.length>s(SIG2).length&&h(SIG1,VAR.length-1),h(SIG3,VAR)
|
|
157
|
+
|
|
158
|
+
Returns match dict or None.
|
|
159
|
+
"""
|
|
160
|
+
pattern = re.compile(
|
|
161
|
+
r'(\w+)\.length===0\?' # VAR.length===0?
|
|
162
|
+
r'\((\w+)\.set\(!1\),(\w+)\.set\(!1\),' # (STORE1.set(!1),STORE2.set(!1),
|
|
163
|
+
r'(\w+\([^)]+\))\)' # h(f,0))
|
|
164
|
+
r':' # :
|
|
165
|
+
r'\1\.length>' # VAR.length>
|
|
166
|
+
r'(\w+\(\w+\))\.length' # s(u).length
|
|
167
|
+
r'&&(\w+\([^)]+\))' # &&h(f,VAR.length-1)
|
|
168
|
+
r',(\w+\(\w+,\1\))' # ,h(u,VAR)
|
|
169
|
+
)
|
|
170
|
+
for m in pattern.finditer(content):
|
|
171
|
+
# Verify it's inside a .subscribe() callback
|
|
172
|
+
before = content[max(0, m.start() - 300):m.start()]
|
|
173
|
+
if '.subscribe(' in before and ('??[]' in before or '||[]' in before):
|
|
174
|
+
return {
|
|
175
|
+
'var': m.group(1), # S (the array variable)
|
|
176
|
+
'store1': m.group(2), # Jr (showControls)
|
|
177
|
+
'store2': m.group(3), # bn (showArtifacts)
|
|
178
|
+
'hide_tail': m.group(4), # h(f,0)
|
|
179
|
+
'getter': m.group(5), # s(u)
|
|
180
|
+
'show_tail': m.group(6), # h(f,S.length-1)
|
|
181
|
+
'update': m.group(7), # h(u,S)
|
|
182
|
+
'full_match': m.group(0),
|
|
183
|
+
'start': m.start(),
|
|
184
|
+
'end': m.end(),
|
|
185
|
+
}
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _find_artifact_store(content, subscribe_pos):
|
|
190
|
+
"""Find the .subscribe() store name closest before the pattern."""
|
|
191
|
+
before = content[max(0, subscribe_pos - 300):subscribe_pos]
|
|
192
|
+
# Find ALL subscribe calls, take the LAST (closest to the pattern)
|
|
193
|
+
all_matches = list(re.finditer(r'(\w+)\.subscribe\(\w+=>\{', before))
|
|
194
|
+
return all_matches[-1].group(1) if all_matches else None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def extract_store_names(content):
|
|
198
|
+
"""Extract store variable names from the subscribe pattern.
|
|
199
|
+
|
|
200
|
+
Returns dict with artifact_store, show_controls, show_artifacts, var, or None.
|
|
201
|
+
"""
|
|
202
|
+
info = _find_subscribe_pattern(content)
|
|
203
|
+
if not info:
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
art_store = _find_artifact_store(content, info['start'])
|
|
207
|
+
return {
|
|
208
|
+
'artifact_store': art_store,
|
|
209
|
+
'show_controls': info['store1'],
|
|
210
|
+
'show_artifacts': info['store2'],
|
|
211
|
+
'var': info['var'],
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def apply_patch():
|
|
216
|
+
"""Apply both patches: subscribe + getContents auto-show"""
|
|
217
|
+
chunk_file = find_chunk_file()
|
|
218
|
+
if not chunk_file:
|
|
219
|
+
print("ERROR: Could not find JS chunk with Artifacts patterns", file=sys.stderr)
|
|
220
|
+
print(f" Searched in: {BUILD_CHUNKS_DIR}/*.js", file=sys.stderr)
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
print(f" Found chunk: {os.path.basename(chunk_file)}")
|
|
224
|
+
|
|
225
|
+
with open(chunk_file, "r", encoding="utf-8") as f:
|
|
226
|
+
content = f.read()
|
|
227
|
+
|
|
228
|
+
# --- Idempotency short-circuit ---
|
|
229
|
+
# If the marker is already present anywhere in the chunk, the patch has
|
|
230
|
+
# been applied by a previous run (or by a previous image build layer).
|
|
231
|
+
# Declare success without mutating the file.
|
|
232
|
+
if IDEMPOTENCY_MARKER in content:
|
|
233
|
+
print(f"ALREADY PATCHED: {os.path.basename(chunk_file)} contains {IDEMPOTENCY_MARKER}")
|
|
234
|
+
return True
|
|
235
|
+
|
|
236
|
+
# Legacy marker fallback: pre-v0.9.1.0 runs injected wrapped-else-branch
|
|
237
|
+
# shape without a comment marker. Recognise those as already-patched too
|
|
238
|
+
# so rebuilds of 0.8.12 images continue to succeed.
|
|
239
|
+
legacy_subscribe = bool(SUBSCRIBE_PATCHED_MARKER.search(content))
|
|
240
|
+
|
|
241
|
+
# Extract store variable names (required for both patch sites)
|
|
242
|
+
stores = extract_store_names(content)
|
|
243
|
+
if not stores and not legacy_subscribe:
|
|
244
|
+
print("ERROR: Could not extract store variable names", file=sys.stderr)
|
|
245
|
+
return False
|
|
246
|
+
|
|
247
|
+
if stores:
|
|
248
|
+
print(f" Stores: artifact={stores['artifact_store']}, "
|
|
249
|
+
f"controls={stores['show_controls']}, "
|
|
250
|
+
f"artifacts={stores['show_artifacts']}")
|
|
251
|
+
|
|
252
|
+
patched = False
|
|
253
|
+
|
|
254
|
+
# --- Patch 1: Subscribe in Artifacts.svelte ---
|
|
255
|
+
if legacy_subscribe:
|
|
256
|
+
print(" Patch 1 (subscribe): already applied (legacy marker)")
|
|
257
|
+
subscribe_already = True
|
|
258
|
+
else:
|
|
259
|
+
subscribe_already = False
|
|
260
|
+
info = _find_subscribe_pattern(content)
|
|
261
|
+
if info:
|
|
262
|
+
store1 = info['store1'] # showControls
|
|
263
|
+
store2 = info['store2'] # showArtifacts
|
|
264
|
+
old = info['full_match']
|
|
265
|
+
|
|
266
|
+
var_name = info['var']
|
|
267
|
+
hide_tail = info['hide_tail']
|
|
268
|
+
getter = info['getter']
|
|
269
|
+
show_tail = info['show_tail']
|
|
270
|
+
update = info['update']
|
|
271
|
+
|
|
272
|
+
new = (
|
|
273
|
+
f'{var_name}.length===0?'
|
|
274
|
+
f'({store1}.set(!1),{store2}.set(!1),{hide_tail})'
|
|
275
|
+
f':{IDEMPOTENCY_MARKER}({var_name}.length>{getter}.length&&{show_tail},'
|
|
276
|
+
f'{store2}.set(!0),{store1}.set(!0))'
|
|
277
|
+
f',{update}'
|
|
278
|
+
)
|
|
279
|
+
print(f" Patch 1 (subscribe):")
|
|
280
|
+
print(f" Old: {old}")
|
|
281
|
+
print(f" New: {new}")
|
|
282
|
+
content = content[:info['start']] + new + content[info['end']:]
|
|
283
|
+
patched = True
|
|
284
|
+
else:
|
|
285
|
+
print(" WARNING: Could not find subscribe pattern for patch 1")
|
|
286
|
+
|
|
287
|
+
# --- Patch 2: getContents in Chat.svelte ---
|
|
288
|
+
# Find: ARTIFACT_STORE.set(VAR)}, near type:"iframe"
|
|
289
|
+
# Handles 3 cases:
|
|
290
|
+
# a) Original: da.set(q)},
|
|
291
|
+
# b) Old patch: da.set(q),q.length>0&&(bn.set(!0),Jr.set(!0))},
|
|
292
|
+
# c) New patch: da.set(q),/* MARKER */q.length>0&&setTimeout(...)},
|
|
293
|
+
art_store = stores['artifact_store'] if stores else None
|
|
294
|
+
show_art = stores['show_artifacts'] if stores else None
|
|
295
|
+
show_ctrl = stores['show_controls'] if stores else None
|
|
296
|
+
|
|
297
|
+
# If subscribe was already patched (legacy marker) but store extraction returned
|
|
298
|
+
# None (legacy-wrapped shape doesn't match _find_subscribe_pattern), attempt a
|
|
299
|
+
# fallback to derive art_store from the getContents context. Without this,
|
|
300
|
+
# Patch 2 would be silently skipped while the script still exits success.
|
|
301
|
+
if subscribe_already and art_store is None:
|
|
302
|
+
# Fallback: look for STORE.set(VAR)}, immediately after type:"iframe"
|
|
303
|
+
fallback_pat = re.compile(
|
|
304
|
+
r'type:"iframe"[^}]{0,400}?(\w+)\.set\(\w+\)\},'
|
|
305
|
+
)
|
|
306
|
+
fb_match = fallback_pat.search(content)
|
|
307
|
+
if fb_match:
|
|
308
|
+
art_store = fb_match.group(1)
|
|
309
|
+
print(f" Fallback store extraction succeeded: art_store={art_store}")
|
|
310
|
+
else:
|
|
311
|
+
print(
|
|
312
|
+
"ERROR: legacy chunk patched but artifact store name could not be "
|
|
313
|
+
"derived for Patch 2 verification",
|
|
314
|
+
file=sys.stderr,
|
|
315
|
+
)
|
|
316
|
+
return False
|
|
317
|
+
|
|
318
|
+
# CR PR#76 finding #3 (Critical): on the legacy fallback path,
|
|
319
|
+
# show_art/show_ctrl stay None because _find_subscribe_pattern did
|
|
320
|
+
# not match the wrapped legacy shape. If we then call _build_new_patch
|
|
321
|
+
# to upgrade Patch 2 (Case b), the f-string interpolates the literal
|
|
322
|
+
# word "None" into the JS, producing `None.set(!0),None.set(!0)` —
|
|
323
|
+
# a runtime ReferenceError in the browser that silently breaks
|
|
324
|
+
# auto-show. Refuse the upgrade in that case; the legacy patch keeps
|
|
325
|
+
# working as it did before.
|
|
326
|
+
if subscribe_already and (show_art is None or show_ctrl is None):
|
|
327
|
+
print(
|
|
328
|
+
" Patch 2 (getContents): skipping upgrade on legacy chunk — "
|
|
329
|
+
"show_artifacts/show_controls names not derivable from this "
|
|
330
|
+
"build's subscribe shape; legacy Patch 2 (no setTimeout) "
|
|
331
|
+
"remains in place. To force upgrade, rebuild the chunk from "
|
|
332
|
+
"stock Open WebUI and re-apply.",
|
|
333
|
+
file=sys.stderr,
|
|
334
|
+
)
|
|
335
|
+
# Treat this as a no-op success: subscribe-side patch is fine,
|
|
336
|
+
# legacy getContents-side patch is fine, only the optional
|
|
337
|
+
# upgrade is skipped. Returning True keeps the build green.
|
|
338
|
+
return True
|
|
339
|
+
|
|
340
|
+
if not art_store:
|
|
341
|
+
print(" WARNING: Could not determine artifact store name, skipping patch 2")
|
|
342
|
+
else:
|
|
343
|
+
getcontents_already = False
|
|
344
|
+
replaced_gc = False
|
|
345
|
+
|
|
346
|
+
def _build_new_patch(var_name):
|
|
347
|
+
return (
|
|
348
|
+
f'{art_store}.set({var_name}),'
|
|
349
|
+
f'{IDEMPOTENCY_MARKER}'
|
|
350
|
+
f'{var_name}.length>0&&'
|
|
351
|
+
f'setTimeout(()=>({show_art}.set(!0),{show_ctrl}.set(!0)),300)'
|
|
352
|
+
f'}},'
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# Case c: Check if already patched with setTimeout
|
|
356
|
+
setTimeout_pattern = re.compile(
|
|
357
|
+
re.escape(art_store) + r'\.set\((\w+)\),(?:/\*[^*]*\*/)?\1\.length>0&&setTimeout'
|
|
358
|
+
)
|
|
359
|
+
for match in setTimeout_pattern.finditer(content):
|
|
360
|
+
before = content[max(0, match.start() - 500):match.start()]
|
|
361
|
+
if GETCONTENTS_CONTEXT in before:
|
|
362
|
+
getcontents_already = True
|
|
363
|
+
print(" Patch 2 (getContents): already applied (setTimeout)")
|
|
364
|
+
break
|
|
365
|
+
|
|
366
|
+
if not getcontents_already:
|
|
367
|
+
# Case b: Old patch without setTimeout -- upgrade it
|
|
368
|
+
old_patch_pattern = re.compile(
|
|
369
|
+
re.escape(art_store) + r'\.set\((\w+)\),'
|
|
370
|
+
r'\1\.length>0&&'
|
|
371
|
+
r'\(\w+\.set\(!0\),\w+\.set\(!0\)\)'
|
|
372
|
+
r'\},'
|
|
373
|
+
)
|
|
374
|
+
for match in old_patch_pattern.finditer(content):
|
|
375
|
+
before = content[max(0, match.start() - 500):match.start()]
|
|
376
|
+
if GETCONTENTS_CONTEXT not in before:
|
|
377
|
+
continue
|
|
378
|
+
var_name = match.group(1)
|
|
379
|
+
old = match.group(0)
|
|
380
|
+
new = _build_new_patch(var_name)
|
|
381
|
+
print(f" Patch 2 (getContents upgrade to setTimeout):")
|
|
382
|
+
print(f" Old: {old}")
|
|
383
|
+
print(f" New: {new}")
|
|
384
|
+
content = content[:match.start()] + new + content[match.end():]
|
|
385
|
+
replaced_gc = True
|
|
386
|
+
patched = True
|
|
387
|
+
break
|
|
388
|
+
|
|
389
|
+
if not getcontents_already and not replaced_gc:
|
|
390
|
+
# Case a: Original unpatched -- STORE.set(VAR)},
|
|
391
|
+
getcontents_pattern = re.compile(
|
|
392
|
+
re.escape(art_store) + r'\.set\((\w+)\)\},'
|
|
393
|
+
)
|
|
394
|
+
for match in getcontents_pattern.finditer(content):
|
|
395
|
+
var_name = match.group(1)
|
|
396
|
+
before = content[max(0, match.start() - 500):match.start()]
|
|
397
|
+
if GETCONTENTS_CONTEXT not in before:
|
|
398
|
+
continue
|
|
399
|
+
old = match.group(0)
|
|
400
|
+
new = _build_new_patch(var_name)
|
|
401
|
+
print(f" Patch 2 (getContents):")
|
|
402
|
+
print(f" Old: {old}")
|
|
403
|
+
print(f" New: {new}")
|
|
404
|
+
content = content[:match.start()] + new + content[match.end():]
|
|
405
|
+
replaced_gc = True
|
|
406
|
+
patched = True
|
|
407
|
+
break
|
|
408
|
+
|
|
409
|
+
if not getcontents_already and not replaced_gc:
|
|
410
|
+
print(" WARNING: Could not find getContents pattern for patch 2")
|
|
411
|
+
|
|
412
|
+
if not patched and not subscribe_already and not getcontents_already:
|
|
413
|
+
print("ERROR: No patches applied", file=sys.stderr)
|
|
414
|
+
return False
|
|
415
|
+
|
|
416
|
+
# Write patched content
|
|
417
|
+
with open(chunk_file, "w", encoding="utf-8") as f:
|
|
418
|
+
f.write(content)
|
|
419
|
+
|
|
420
|
+
# Cache bust: copy chunk to timestamped name and update references
|
|
421
|
+
# Old file kept so browsers with cached parent modules still work
|
|
422
|
+
cache_bust_chunk(chunk_file)
|
|
423
|
+
|
|
424
|
+
print(f"PATCHED! File: {os.path.basename(chunk_file)}")
|
|
425
|
+
return True
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
if __name__ == "__main__":
|
|
429
|
+
print("Applying Artifacts auto-show patch to Open WebUI frontend...")
|
|
430
|
+
success = apply_patch()
|
|
431
|
+
if not success:
|
|
432
|
+
print(
|
|
433
|
+
"ERROR: fix_artifacts_auto_show anchor not found in "
|
|
434
|
+
f"{BUILD_CHUNKS_DIR}/*.js -- upstream may have refactored. "
|
|
435
|
+
"Check v0.9.5 source + update regex. "
|
|
436
|
+
"Refusing to produce a silently-broken image.",
|
|
437
|
+
file=sys.stderr,
|
|
438
|
+
)
|
|
439
|
+
sys.exit(1)
|
|
440
|
+
print("PATCHED: fix_artifacts_auto_show applied successfully.")
|
|
441
|
+
sys.exit(0)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
3
|
+
# Copyright (c) 2025 Open Computer Use Contributors
|
|
4
|
+
"""
|
|
5
|
+
Patch for Open WebUI 0.9.5: append <attached_files> instead of prepend.
|
|
6
|
+
|
|
7
|
+
Problem:
|
|
8
|
+
add_file_context() prepends <attached_files> to the beginning of user message.
|
|
9
|
+
This breaks prompt cache: each new file changes the start of the message,
|
|
10
|
+
invalidating the entire cached prefix.
|
|
11
|
+
|
|
12
|
+
Solution:
|
|
13
|
+
Append <attached_files> to the end of the message -- system prompt cache
|
|
14
|
+
and previous messages are preserved.
|
|
15
|
+
|
|
16
|
+
Note:
|
|
17
|
+
Zip misalignment (user_messages filter) and format_file_tag() are already
|
|
18
|
+
fixed upstream (PR #21878). This patch affects ONLY the insertion position.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import os
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
_PATCH_TARGET_OVERRIDE = os.environ.get("_PATCH_TARGET_OVERRIDE", "")
|
|
25
|
+
MIDDLEWARE_PATH = _PATCH_TARGET_OVERRIDE or "/app/backend/open_webui/utils/middleware.py"
|
|
26
|
+
|
|
27
|
+
PATCH_MARKER = "attached_files_append"
|
|
28
|
+
NEW_PATCH_MARKER = "FIX_ATTACHED_FILES_POSITION"
|
|
29
|
+
|
|
30
|
+
# Exact v0.8.11-0.9.2 code — prepend file_context before content
|
|
31
|
+
SEARCH_PATTERN = """\
|
|
32
|
+
content = message.get('content', '')
|
|
33
|
+
if isinstance(content, list):
|
|
34
|
+
message['content'] = [{'type': 'text', 'text': file_context}] + content
|
|
35
|
+
else:
|
|
36
|
+
message['content'] = file_context + content"""
|
|
37
|
+
|
|
38
|
+
# Replace with append — file_context goes AFTER content (prompt cache friendly)
|
|
39
|
+
REPLACE_PATTERN = """\
|
|
40
|
+
# PATCH: attached_files_append — append to end, not prepend (prompt cache friendly); FIX_ATTACHED_FILES_POSITION
|
|
41
|
+
content = message.get('content', '')
|
|
42
|
+
if isinstance(content, list):
|
|
43
|
+
message['content'] = content + [{'type': 'text', 'text': file_context}]
|
|
44
|
+
else:
|
|
45
|
+
message['content'] = (content + '\\n' + file_context) if content else file_context"""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def apply_patch():
|
|
49
|
+
if not os.path.exists(MIDDLEWARE_PATH):
|
|
50
|
+
print(
|
|
51
|
+
f"ERROR: fix_attached_files_position target file {MIDDLEWARE_PATH} not found. "
|
|
52
|
+
"Refusing to produce a silently-broken image.",
|
|
53
|
+
file=sys.stderr,
|
|
54
|
+
)
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
|
|
57
|
+
with open(MIDDLEWARE_PATH, "r", encoding="utf-8") as f:
|
|
58
|
+
content = f.read()
|
|
59
|
+
|
|
60
|
+
if PATCH_MARKER in content or NEW_PATCH_MARKER in content:
|
|
61
|
+
which = NEW_PATCH_MARKER if NEW_PATCH_MARKER in content else PATCH_MARKER
|
|
62
|
+
print(f"ALREADY PATCHED: {MIDDLEWARE_PATH} contains {which}")
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
if SEARCH_PATTERN not in content:
|
|
66
|
+
print(
|
|
67
|
+
f"ERROR: fix_attached_files_position anchor (add_file_context prepend block) "
|
|
68
|
+
f"not found in {MIDDLEWARE_PATH} — upstream may have refactored add_file_context. "
|
|
69
|
+
"Refusing to produce a silently-broken image.",
|
|
70
|
+
file=sys.stderr,
|
|
71
|
+
)
|
|
72
|
+
sys.exit(1)
|
|
73
|
+
|
|
74
|
+
content = content.replace(SEARCH_PATTERN, REPLACE_PATTERN, 1)
|
|
75
|
+
|
|
76
|
+
with open(MIDDLEWARE_PATH, "w", encoding="utf-8") as f:
|
|
77
|
+
f.write(content)
|
|
78
|
+
|
|
79
|
+
print("PATCHED: fix_attached_files_position applied successfully.")
|
|
80
|
+
print(" <attached_files> appended to end of message (prompt cache friendly)")
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
print("Applying attached-files-position patch to Open WebUI...")
|
|
86
|
+
success = apply_patch()
|
|
87
|
+
sys.exit(0 if success else 1)
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-License-Identifier: FSL-1.1-Apache-2.0
|
|
3
|
+
# Copyright (c) 2025 Open Computer Use Contributors
|
|
4
|
+
"""
|
|
5
|
+
Patch for Open WebUI: truncate large tool call arguments in HTML attributes
|
|
6
|
+
+ base64 storage of full arguments for reconstruction.
|
|
7
|
+
|
|
8
|
+
Problem: serialize_output() stores tool call arguments in an
|
|
9
|
+
HTML attribute <details arguments="html.escape(json.dumps(arguments))">.
|
|
10
|
+
When arguments are large (str_replace with multi-KB HTML), triple encoding
|
|
11
|
+
(json.dumps -> html.escape) inflates the attribute to 30-65+ KB.
|
|
12
|
+
The frontend markdown parser (marked) breaks on large attributes, UI freezes
|
|
13
|
+
on "Executing [tool]..." forever.
|
|
14
|
+
|
|
15
|
+
Solution:
|
|
16
|
+
1. arguments="..." -- truncated via _truncate_for_attr() > 2KB (for display)
|
|
17
|
+
2. arguments-raw="..." -- base64-encoded full JSON (for reconstruct_tool_messages)
|
|
18
|
+
|
|
19
|
+
Base64 is safe for HTML attributes: charset [A-Za-z0-9+/=], no special characters.
|
|
20
|
+
Regex [^"]* in the attribute parser runs O(n) without backtracking.
|
|
21
|
+
|
|
22
|
+
Frontend regex /(\\w+)="([^"]*)"/g skips arguments-raw (hyphen does not match \\w),
|
|
23
|
+
so base64 data is invisible to the frontend.
|
|
24
|
+
|
|
25
|
+
See https://github.com/open-webui/open-webui/issues/18743
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
_PATCH_TARGET_OVERRIDE = os.environ.get("_PATCH_TARGET_OVERRIDE", "")
|
|
32
|
+
MIDDLEWARE_PATH = _PATCH_TARGET_OVERRIDE or "/app/backend/open_webui/utils/middleware.py"
|
|
33
|
+
|
|
34
|
+
PATCH_MARKER = "_truncate_for_attr"
|
|
35
|
+
NEW_PATCH_MARKER = "FIX_LARGE_TOOL_ARGS"
|
|
36
|
+
|
|
37
|
+
FUNCTION_CODE = '''
|
|
38
|
+
# === PATCH: _truncate_for_attr + _b64_encode_args — fix UI freeze + preserve args for model ===
|
|
39
|
+
# FIX_LARGE_TOOL_ARGS
|
|
40
|
+
import base64 as _b64_module
|
|
41
|
+
|
|
42
|
+
_MAX_TOOL_ATTR_LEN = 2_000 # ~2KB before html.escape — tool panel is small, no point showing more
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _truncate_for_attr(data, max_len=_MAX_TOOL_ATTR_LEN, **kwargs):
|
|
46
|
+
"""Truncate tool arguments for HTML attribute display.
|
|
47
|
+
|
|
48
|
+
Drop-in replacement for json.dumps() with size check.
|
|
49
|
+
Returns json.dumps() output for normal data, truncated summary for oversized.
|
|
50
|
+
If data has a 'description' field, shows it in the summary.
|
|
51
|
+
Only used for the display `arguments` attribute, NOT for `arguments-raw`.
|
|
52
|
+
"""
|
|
53
|
+
serialized = json.dumps(data, **kwargs)
|
|
54
|
+
if len(serialized) <= max_len:
|
|
55
|
+
return serialized
|
|
56
|
+
# Try to extract description for a meaningful summary
|
|
57
|
+
desc = None
|
|
58
|
+
try:
|
|
59
|
+
obj = data if isinstance(data, dict) else (json.loads(data) if isinstance(data, str) else None)
|
|
60
|
+
if isinstance(obj, dict):
|
|
61
|
+
desc = obj.get("description") or obj.get("desc")
|
|
62
|
+
except Exception:
|
|
63
|
+
pass
|
|
64
|
+
size_kb = f"{len(serialized) / 1024:.1f}"
|
|
65
|
+
if desc:
|
|
66
|
+
result = {"description": str(desc), "_hidden": f"Arguments truncated ({size_kb} KB). Full text available to the model."}
|
|
67
|
+
else:
|
|
68
|
+
result = f"[Arguments hidden ({size_kb} KB). Full text available to the model.]"
|
|
69
|
+
return json.dumps(result, ensure_ascii=False)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _b64_encode_args(data):
|
|
73
|
+
"""Base64-encode tool arguments for safe storage in HTML attribute.
|
|
74
|
+
|
|
75
|
+
Used for `arguments-raw` attribute. Base64 charset [A-Za-z0-9+/=] has no
|
|
76
|
+
HTML special characters, so no html.escape() needed and no regex backtracking.
|
|
77
|
+
|
|
78
|
+
Note: arguments may be a JSON string (OpenAI spec) or a dict.
|
|
79
|
+
If already a string, use as-is; otherwise json.dumps() it.
|
|
80
|
+
"""
|
|
81
|
+
try:
|
|
82
|
+
raw = data if isinstance(data, str) else json.dumps(data, ensure_ascii=False)
|
|
83
|
+
result = _b64_module.b64encode(raw.encode()).decode()
|
|
84
|
+
return result
|
|
85
|
+
except Exception as e:
|
|
86
|
+
log.debug("_b64_encode_args failed: %s", e)
|
|
87
|
+
return ""
|
|
88
|
+
# === END PATCH ===
|
|
89
|
+
'''
|
|
90
|
+
|
|
91
|
+
# Search pattern: the original html.escape(json.dumps(arguments)) inside f-string attribute
|
|
92
|
+
OLD_ARGS = 'arguments="{html.escape(json.dumps(arguments))}"'
|
|
93
|
+
|
|
94
|
+
# Replace with: truncated display attribute + base64 raw attribute
|
|
95
|
+
NEW_ARGS = 'arguments="{html.escape(_truncate_for_attr(arguments))}" arguments-raw="{_b64_encode_args(arguments)}"'
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def apply_patch():
|
|
99
|
+
"""Apply patch to middleware.py"""
|
|
100
|
+
|
|
101
|
+
if not os.path.exists(MIDDLEWARE_PATH):
|
|
102
|
+
print(
|
|
103
|
+
f"ERROR: fix_large_tool_args target file {MIDDLEWARE_PATH} not found. "
|
|
104
|
+
"Refusing to produce a silently-broken image.",
|
|
105
|
+
file=sys.stderr,
|
|
106
|
+
)
|
|
107
|
+
sys.exit(1)
|
|
108
|
+
|
|
109
|
+
with open(MIDDLEWARE_PATH, "r", encoding="utf-8") as f:
|
|
110
|
+
content = f.read()
|
|
111
|
+
|
|
112
|
+
if PATCH_MARKER in content or NEW_PATCH_MARKER in content:
|
|
113
|
+
print(f"ALREADY PATCHED: {MIDDLEWARE_PATH} contains {PATCH_MARKER}")
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
# 1. Insert functions after imports
|
|
117
|
+
import_marker = "from open_webui.models.chats import Chats"
|
|
118
|
+
marker_idx = content.find(import_marker)
|
|
119
|
+
if marker_idx < 0:
|
|
120
|
+
print(
|
|
121
|
+
f"ERROR: fix_large_tool_args import anchor 'from open_webui.models.chats "
|
|
122
|
+
f"import Chats' not found in {MIDDLEWARE_PATH} — upstream may have "
|
|
123
|
+
"restructured imports. Refusing to produce a silently-broken image.",
|
|
124
|
+
file=sys.stderr,
|
|
125
|
+
)
|
|
126
|
+
sys.exit(1)
|
|
127
|
+
|
|
128
|
+
eol_idx = content.index("\n", marker_idx) + 1
|
|
129
|
+
content = content[:eol_idx] + FUNCTION_CODE + content[eol_idx:]
|
|
130
|
+
print(" Inserted _truncate_for_attr() + _b64_encode_args() functions after imports")
|
|
131
|
+
|
|
132
|
+
# 2. Replace arguments attribute pattern — expected EXACTLY 2 occurrences in serialize_output
|
|
133
|
+
occurrences = content.count(OLD_ARGS)
|
|
134
|
+
if occurrences != 2:
|
|
135
|
+
print(
|
|
136
|
+
f"ERROR: fix_large_tool_args expected 2 occurrences of OLD_ARGS f-string in "
|
|
137
|
+
f"serialize_output, found {occurrences}. v0.9.5 upstream may have restructured. "
|
|
138
|
+
"Refusing to produce a silently-broken image.",
|
|
139
|
+
file=sys.stderr,
|
|
140
|
+
)
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
content = content.replace(OLD_ARGS, NEW_ARGS)
|
|
144
|
+
print(f" Replaced {occurrences} occurrence(s): arguments + arguments-raw")
|
|
145
|
+
|
|
146
|
+
with open(MIDDLEWARE_PATH, "w", encoding="utf-8") as f:
|
|
147
|
+
f.write(content)
|
|
148
|
+
|
|
149
|
+
print("PATCHED: fix_large_tool_args applied successfully.")
|
|
150
|
+
return True
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
print("Applying large tool arguments patch to Open WebUI...")
|
|
155
|
+
success = apply_patch()
|
|
156
|
+
sys.exit(0 if success else 1)
|