Skip to content

merge: integrate main (33 commits incl. AUTH_ENABLED) into feat/agent-skills-runtime#5

Merged
djuillard merged 164 commits into
feat/agent-skills-runtimefrom
merge/main-into-feat-skills-2026-05-08
May 8, 2026
Merged

merge: integrate main (33 commits incl. AUTH_ENABLED) into feat/agent-skills-runtime#5
djuillard merged 164 commits into
feat/agent-skills-runtimefrom
merge/main-into-feat-skills-2026-05-08

Conversation

@djuillard

Copy link
Copy Markdown

Summary

Brings the freshly-synced main branch (post PR #4) into our long-lived feature branch feat/agent-skills-runtime. The merge direction is main → feat-branch, not the other way aroundfeat/agent-skills-runtime is the production branch (built into code-interpreter:agent-skills) and continues to live independently.

The headline reason for this merge: AUTH_ENABLED flag + Basic auth via URL credentials (upstream commit 67d2a18) — needed to make our self-hosted code-interpreter compatible with LibreChat dev again. See security-toolkit#96 for the corresponding LibreChat side.

What's coming in (33 commits from main)

  • 67d2a18 feat: AUTH_ENABLED + Basic auth via URL credentials (LibreChat dev compat)
  • 64b4494 refactor: Replace MinIO with S3-compatible storage (Garage)
  • 9bf6479 feat: Sandbox network access for skill installations
  • 3b5794b feat(files): Update file upload restrictions and session limits
  • e85e9e8 fix: Match LibreChat's Unicode sanitization
  • 74bb001 chore: Simplify CI/CD (remove nightly, slim ci.yml, keep release)
  • 8323225 chore: Consolidate compose files, update docs for S3/Garage
  • Several dependabot bumps

Conflicts resolved (5 zones in 4 files)

All conflicts were in src/services/sandbox/* and src/services/programmatic.pyzero conflicts on auth/middleware (the feature branch hadn't touched the auth path).

# File Resolution Why
1 executor.py (lang-with-/proc list) COMBINED ("java", "rs", "py", "python", "bash") OURS gave /proc to Python (legacy skills), THEIRS to bash (LibreChat bash_tool migration). Both paths coexist on this fork until skills migrate to bash exclusively.
2 executor.py (NODE_PATH) THEIRS (deps_root) Consistency with PYTHONPATH/PIP_TARGET/GOPATH already on feat. /opt/skill-deps is auto-created at startup when ENABLE_SANDBOX_NETWORK=true.
3 nsjail.py (seccomp bind) COMBINED ("py", "python", "java", "bash") Same logic as #1: LibreOffice uses AF_UNIX sockets regardless of which language invokes it.
4 programmatic.py (PTC wrapper) COMBINED selective — OURS on /proc + THEIRS on tmpfs/skill-deps hardening Keep /proc accessible (PTC may invoke soffice for skills); take the BUG-007/BUG-008 hardening on /tmp, /var/tmp, /run/lock, /var/lib/php/sessions, skill-deps (purely additive).
5 pool.py (REPL pool wrapper) COMBINED selective (same as #4) Upstream comment "REPL is Python-only, always safe to mask /proc" doesn't hold for this fork — Python skills shell out to soffice which needs /proc.

Detailed rationale for each resolution is in the merge commit message.

Testing — what to verify after merge

The merged code requires a rebuild of the code-interpreter:agent-skills image and a container restart to take effect. Suggested smoke tests:

  • code-interpreter-api starts cleanly, logs show "Sandbox network access ENABLED" + skill-deps directory prepared
  • /opt/skill-deps exists in the container after startup
  • Existing Python DOCX skills still work (soffice can be invoked from a Python sandbox)
  • New bash sandbox can also invoke soffice (compat for LibreChat bash_tool)
  • Test tests/integration/test_librechat_compat.py passes
  • Test tests/integration/test_auth_disabled.py passes
  • LibreChat upload via Basic-auth-in-URL works (after the LibreChat side switch)

Follow-ups (separate work, after this merges)

  • LibreChat side: change LIBRECHAT_CODE_BASEURL=http://<API_KEY>@code-interpreter-api:8000 in LibreChat/.env to use the new Basic-auth path; rebuild + restart code-interpreter-api; revert the librechat-api:v0.8.5 pin from security-toolkit#96.
  • Future: migrate Python skills to bash entry point (= drop "py", "python" from /proc and seccomp lists). Estimated 4-8h of dev. Tracked separately.

🤖 Generated with Claude Code
via Happy

dependabot Bot and others added 30 commits December 26, 2025 17:48
Bumps [fastapi](https://github.com/fastapi/fastapi) from 0.116.1 to 0.127.1.
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](fastapi/fastapi@0.116.1...0.127.1)

---
updated-dependencies:
- dependency-name: fastapi
  dependency-version: 0.127.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 2 to 3.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](dorny/paths-filter@v2...v3)

---
updated-dependencies:
- dependency-name: dorny/paths-filter
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps node from 20-alpine to 25-alpine.

---
updated-dependencies:
- dependency-name: node
  dependency-version: 25-alpine
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps eclipse-temurin from 17-jdk to 25-jdk.

---
updated-dependencies:
- dependency-name: eclipse-temurin
  dependency-version: 25-jdk
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps rust from 1.85-slim to 1.92-slim.

---
updated-dependencies:
- dependency-name: rust
  dependency-version: 1.92-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.3 to 9.0.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@7.4.3...9.0.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [locust](https://github.com/locustio/locust) from 2.28.0 to 2.42.6.
- [Release notes](https://github.com/locustio/locust/releases)
- [Changelog](https://github.com/locustio/locust/blob/master/CHANGELOG.md)
- [Commits](locustio/locust@2.28.0...2.42.6)

---
updated-dependencies:
- dependency-name: locust
  dependency-version: 2.42.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.9.2 to 2.12.5.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](pydantic/pydantic@v2.9.2...v2.12.5)

---
updated-dependencies:
- dependency-name: pydantic
  dependency-version: 2.12.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

Bumps [python-dateutil](https://github.com/dateutil/dateutil) from 2.8.2 to 2.9.0.post0.
- [Release notes](https://github.com/dateutil/dateutil/releases)
- [Changelog](https://github.com/dateutil/dateutil/blob/master/NEWS)
- [Commits](dateutil/dateutil@2.8.2...2.9.0.post0)

---
updated-dependencies:
- dependency-name: python-dateutil
  dependency-version: 2.9.0.post0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- Removed unused imports across multiple files, including asyncio and json.
- Simplified conditional expressions for better clarity in lifespan and execution contexts.
- Adjusted type hints and default values in models for consistency.
- Enhanced formatting of long strings for improved readability in configuration files.
- Replaced MAX_CPU with MAX_CPUS for clarity.
- Marked MAX_CPU_QUOTA as deprecated for future reference.
- Changed instructions from pulling prebuilt Docker images to building the execution environment.
- Updated commands for building Python and all language images accordingly.
- Introduced a new `docker-compose.ghcr.yml` file for deploying the application with pre-built images from GitHub Container Registry.
- Updated `.env.example` to include `DOCKER_IMAGE_REGISTRY` for better configuration management.
- Enhanced the `Settings` class to support dynamic Docker image retrieval based on the specified registry.
- Modified `languages.py` to use images without the registry prefix for better compatibility with the new setup.
- Updated the README to reflect changes in execution environment setup and provide instructions for using local vs. pre-built images.
- Updated the Docker publish workflows to support multi-platform builds for linux/amd64 and linux/arm64 architectures.
…e building logic

- Added `workflow_dispatch` support to `docker-publish.yml` and `execution-env-publish.yml` for manual execution.
- Introduced input option `build_all` in `execution-env-publish.yml` to force build all images.
- Updated logic in `execution-env-publish.yml` to determine target languages based on workflow events and changes to the workflow file.
- Changed echo statements to use single quotes for consistency.
- Updated conditional checks to use the `contains` function for better clarity when determining if the workflow file was modified.
- Added a new filter for `rebuild_all` to trigger builds when specific files change.
- Improved conditional checks to determine when to build all images based on workflow changes.
- Filtered out `rebuild_all` from the changes list for cleaner output.
- Changed the Docker image tag in `docker-compose.ghcr.yml` from `latest` to `dev` for development purposes.
- Enhanced the `Settings` class to include a new field for `docker_image_tag`, allowing dynamic specification of image tags.
- Modified the `get_image_for_language` function in `languages.py` to accept a tag parameter, improving flexibility in image retrieval.
- Changed the default Docker image tag in `docker-compose.ghcr.yml` from `latest` to `dev` to better suit development needs.
- Enhanced the `Settings` class to retrieve the Docker image tag dynamically, allowing for more flexible image management.
- Modified `.env.example` to clarify SSL certificate paths for Docker and non-Docker deployments.
- Updated `docker-compose.ghcr.yml` and `docker-compose.yml` to use a dynamic path for SSL certificates, enhancing flexibility.
- Revised `CONFIGURATION.md` to provide detailed instructions for SSL setup in both Docker and non-Docker environments.
…d service files

- Enhanced the `Settings` class in `__init__.py` for better clarity in Docker image retrieval logic.
- Reformatted the `get_image_for_language` function in `languages.py` for improved readability.
- Adjusted the `ApiKeyRecord` class in `api_key.py` to streamline dictionary comprehension.
- Improved formatting in the `HealthCheckService` class in `health.py` for better alignment.
- Refactored the `ExecutionContext` class in `orchestrator.py` to enhance code structure.
- Improved the formatting of the Docker image retrieval logic in the `Settings` class in `__init__.py`.
- Streamlined dictionary comprehension in the `ApiKeyRecord` class in `api_key.py`.
- Refined the formatting of memory total calculation in the `HealthCheckService` class in `health.py`.
- Enhanced the structure of the `ExecutionContext` class in `orchestrator.py` for better clarity.
- Combined multiple RUN commands into a single layer for R package installations to optimize build time and reduce image size.
- Updated package repository to use Posit Package Manager for improved package management.
refactor: Consolidate R package installations in Dockerfile
- Enhanced the structure and clarity of the bug report and feature request templates.
- Added sections for actual behavior, environment details, and logs/screenshots to improve bug reporting.
- Updated headings for consistency and better readability.
chore: Update issue templates for bug reports and feature requests
- Updated the `get_image_for_language` method to implement fallback logic for Docker images, allowing for a more robust image resolution process.
- Added error handling to provide clear feedback when no suitable Docker image is found.
- Improved security hardening configurations by documenting limitations and applying ulimits for process and file descriptor management.
usnavy13 and others added 28 commits May 5, 2026 23:19
- Enhanced file upload logic to skip extension checks for agent files, allowing skill-priming uploads from the LibreChat host.
- Increased the maximum number of files per session from 300 to 1000 to accommodate larger skill bundles and prevent upload errors.
- Added normalization functions for Python and Bash tool names to ensure compatibility with SDK-generated code.
- Updated file handling in execution services to support new metadata fields, including `inherited`, `modified_from`, and `entity_id`.
- Introduced read-only file handling during uploads, allowing for better management of file permissions in sandbox environments.
- Enhanced unit tests to cover new features and ensure robust validation of file and tool name handling.
…essions

- Egress proxy tunnel test: use IP literal 127.0.0.1 instead of localhost
  to avoid IPv6 resolution mismatch in CI
- Batch upload mock: add missing is_read_only param to fake_store
- Client-replay test: allow inherited file refs in exec response (matches
  LibreChat CodeExecutor.ts contract)
- Bandit B103: suppress intentional 0o1777 chmod on shared skill-deps dir

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ements

feat: Auth, sandbox egress, file handling, and bash batch execution
- Introduced `original_filename` field in the FileInfo model to store pre-sanitization filenames.
- Updated file upload and batch upload functions to include the original filename in metadata.
- Enhanced file listing to return the original filename if available, improving metadata accuracy.
- Adjusted file service methods to handle the new original filename parameter for better file management.
…-pass approach

Align sanitize_filename with LibreChat#12977's sanitizeFilenameSegment:
- NFC-normalize before sanitizing (handles decomposed accents)
- Two-pass: strict ASCII [a-zA-Z0-9._-], permissive non-ASCII (only
  blocks C1 controls U+0080-U+009F)
- Preserves emoji (📊) and ZWJ sequences that \w alone would strip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The fake_store function in TestLibreChatUploadBatch had a fixed
parameter list missing the new original_filename kwarg, causing
a TypeError when the endpoint passed it through.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Updated configuration and environment variables to transition from MinIO to S3 storage, including changes to .env.example and Docker Compose files.
- Introduced a new S3Config class for managing S3 settings and removed the MinIO configuration.
- Refactored file management and state archival services to utilize the S3 client, ensuring compatibility with S3 operations.
- Adjusted health checks and service dependencies to reflect the new S3 storage integration.
- Updated documentation and comments throughout the codebase to replace references to MinIO with S3.
- Changed S3 access and secret keys in .env.example and test configuration to new values.
- Updated Docker Compose files to reflect the new S3 access keys and added default bucket environment variable.
- Modified health check command in Docker Compose to use the new status command for better service monitoring.
- Added RPC settings in garage.toml for improved service configuration.
fix: Preserve Unicode filenames in sanitization and persist original names
- Enhanced functional tests to verify that edits to mounted files produce new outputs with unique file_ids instead of in-place overwrites.
- Updated test descriptions for clarity on expected behavior regarding modified files.
- Introduced a helper function to locate modified files based on the original file_id, ensuring accurate assertions in test cases.
…etup

- Added a temporary filesystem configuration for /tmp with size and mode settings in both Docker Compose files.
- Changed the directory for empty_proc from /tmp to /var/lib/code-interpreter in the Dockerfile and related service files.
- Updated the sandbox execution commands to reflect the new empty_proc path and incorporated dynamic tmpfs size settings.
- Updated tmpfs mount options for /tmp in Docker Compose files to include noexec, nosuid, and nodev for improved security.
- Refactored sandbox execution commands to apply the new tmpfs settings consistently across service files.
- Introduced dynamic handling of skill dependencies with updated mount options to enhance security and isolation.
…rage-s3

Replace MinIO with S3-compatible storage (Garage)
…pipeline

- Remove nightly.yml entirely
- Slim ci.yml from 11 jobs to 3 (static, unit, integration) — PR checks only, no Docker builds
- Release.yml (unchanged) handles multi-arch image builds on merge to main/dev

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tale files

The repo had unnecessary docker-compose.prod.yml and docker-compose.local-test.yml
files. docker-compose.yml is now the single production-ready base (pulls published
GHCR image by default), and docker-compose.override.example.yml handles local dev
overrides. All MinIO references across 10+ docs updated to S3/Garage to match the
migration completed in usnavy13#90. Removed stale Reference/ directory and placeholder
AGENTS.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Release: S3 migration, PTC bash, egress proxy, compose consolidation
…uth via URL credentials)

Merges upstream usnavy13/LibreCodeInterpreter:main into On-Behalf-AI:main.

Notable upstream changes pulled:
- 67d2a18 feat: AUTH_ENABLED flag + Basic auth via URL credentials (LibreChat dev compat)
- 64b4494 refactor: Replace MinIO with S3-compatible storage (Garage)
- 9bf6479 feat: Sandbox network access for skill installations
- 3b5794b feat(files): Update file upload restrictions and session limits
- e85e9e8 fix: Match LibreChat's Unicode sanitization
- 74bb001 chore: Simplify CI/CD — remove nightly, lean PR checks, keep release pipeline
- 8323225 chore: Consolidate compose files, update docs for S3/Garage

Conflict resolution:
- .github/workflows/nightly.yml — accepted upstream deletion (74bb001).
  Our local commit 1032ee9 ("on-change+weekly schedule") aimed to reduce GHA
  minute consumption; upstream's full removal goes in the same direction.
  Going forward we rely on ci.yml (lean PR checks) + release.yml.

Preserved On-Behalf-AI customizations:
- .gitleaks.toml (whitelist upstream test fixtures + docs)
- ci/nightly-on-change-weekly history (commits remain in tree even though
  the file is now deleted)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
sync: merge usnavy13/main (33 commits, incl. AUTH_ENABLED for LibreChat dev compat)
…t/agent-skills-runtime

Brings AUTH_ENABLED + Basic-auth-via-URL-credentials support, S3/Garage,
hardening tmpfs/skill-deps, slim CI, etc. into our skills feature branch.
Required for LibreChat dev compat (PR #12767 dropped X-API-Key from
uploadCodeEnvFile — see security-toolkit#96 for the corresponding LibreChat
workaround).

Conflicts resolved (5 zones in 4 files, all in src/services/sandbox/* +
src/services/programmatic.py, none in auth/middleware):

1. src/services/sandbox/executor.py (lang-with-/proc list):
   COMBINED — keep ("java", "rs", "py", "python", "bash"). OURS gave /proc
   to Python (legacy DOCX/PPTX/XLSX skill path), THEIRS gave it to bash
   (LibreChat bash_tool migration). Both paths coexist on this fork until
   skills are migrated to bash exclusively.

2. src/services/sandbox/executor.py (NODE_PATH):
   THEIRS — use deps_root for consistency with PYTHONPATH/PIP_TARGET/GOPATH
   already on this branch. /opt/skill-deps is auto-created at startup by
   _startup_egress_proxy when ENABLE_SANDBOX_NETWORK=true (which we have).

3. src/services/sandbox/nsjail.py (seccomp bind syscall):
   COMBINED — same logic as conflict 1: ("py", "python", "java", "bash")
   are exempt from bind blocking, because LibreOffice (soffice) uses
   AF_UNIX sockets between oosplash and soffice.bin, regardless of which
   language invokes it. Variable renamed to seccomp_policy (THEIRS, more
   explicit).

4. src/services/programmatic.py (PTC wrapper, /proc + tmpfs hardening):
   COMBINED SELECTIVELY — keep OURS on /proc accessibility (PTC may invoke
   LibreOffice for skills) AND take THEIRS on the tmpfs/skill-deps
   hardening (BUG-007 + BUG-008): noexec,nosuid,nodev on /tmp, /var/tmp,
   /run/lock, /var/lib/php/sessions; nosuid,nodev bind on skill-deps.

5. src/services/sandbox/pool.py (REPL pool wrapper, /proc + tmpfs):
   COMBINED SELECTIVELY — same as conflict 4. Note: upstream comment
   "REPL is Python-only, always safe to mask /proc" doesn't hold for this
   fork because Python skills shell out to soffice which requires /proc.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants