diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 43081c9..f3b85c5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -2,12 +2,20 @@ FROM mcr.microsoft.com/devcontainers/base:noble # VS Code commit ID for devcontainer compatibility. Can be overridden at build time via build args. # Default chosen for current stable VS Code Server version used in this repository. -ARG VSCODE_COMMIT=f220831ea2d946c0dcb0f3eaa480eb435a2c1260 +ARG VSCODE_COMMIT=7d842fb85a0275a4a8e4d7e040d2625abbf7f084 ENV VSCODE_COMMIT=${VSCODE_COMMIT} # Copy and run VS Code installation files COPY ./vscode-init /opt/vscode-init + +# Copy Codex config +COPY ./codex-config.toml /root/.codex/config.toml + +# Copy Continue Dev config +COPY ./continue-config.yaml /root/.continue/config.yaml +COPY ./continue.env /root/.continue/.env + RUN cd /opt/vscode-init \ && ./00-install-vscode-server.sh ${VSCODE_COMMIT} \ && ./01-install-extensions.sh ${VSCODE_COMMIT} \ diff --git a/.devcontainer/codex-config.toml b/.devcontainer/codex-config.toml new file mode 100644 index 0000000..d98fd3f --- /dev/null +++ b/.devcontainer/codex-config.toml @@ -0,0 +1,74 @@ +# Default Codex Configuration for gpt-oss:20b via Ollama +# This configuration sets up Codex to use the gpt-oss:20b model through a local Ollama instance + +# Default model to use +model = "gpt-oss:20b" + +# Default model provider +model_provider = "ollama" + +# Approval policy - change to "never" for fully automated operation, or "untrusted" for safety +# approval_policy = "untrusted" +approval_policy = "on-request" + +# Sandbox mode for security +# sandbox_mode = "read-only" +sandbox_mode = "workspace-write" + +# Model provider configurations +[model_providers.ollama] +# Display name for the provider +name = "Ollama Local" + +# Base URL for Ollama API (default local installation) +# Change this if your Ollama instance is running on a different host/port +base_url = "http://host.containers.internal:11434/v1" + +# Environment variable for API key (Ollama typically doesn't require authentication for local usage) +# You can set OLLAMA_API_KEY if your setup requires it, or remove this line +# env_key = "OLLAMA_API_KEY" + +# Use the chat completions API (compatible with OpenAI API format) +wire_api = "chat" + +# Optional: Additional configuration +# request_max_retries = 4 +# stream_max_retries = 5 + +# Optional: Custom HTTP headers if needed +# [model_providers.ollama.http_headers] +# "User-Agent" = "Codex-CLI/1.0" + +# Optional: Query parameters if needed +# [model_providers.ollama.query_params] +# "stream" = "true" + +# History configuration +[history] +persistence = "save-all" + +# File opener configuration for VS Code integration +file_opener = "vscode" + +# Optional: Hide reasoning events for cleaner output +# hide_agent_reasoning = true + +# Optional: MCP servers configuration (uncomment and configure as needed) +# [mcp_servers.example-server] +# command = "npx" +# args = ["-y", "@your/mcp-server"] +# env = { "API_KEY" = "your-api-key" } + +# Optional: Custom instructions file +# experimental_instructions_file = "/path/to/your/instructions.md" + +# Optional: TUI configuration +[tui] +notifications = false + +# Optional: Shell environment policy +[shell_environment_policy] +inherit = "core" +ignore_default_excludes = false +exclude = [] +set = {} \ No newline at end of file diff --git a/.devcontainer/continue-config.yaml b/.devcontainer/continue-config.yaml new file mode 100644 index 0000000..3da790d --- /dev/null +++ b/.devcontainer/continue-config.yaml @@ -0,0 +1,101 @@ +name: Local Assistant +version: 1.0.0 +schema: v1 +models: + # - name: Llama 3.1 8B + # model: llama3.1:8b + # provider: openai + # apiBase: ${{ secrets.OPENWEB_BASE_URL }} + # apiKey: ${{ secrets.OPENWEB_API_KEY }} + # roles: + # - chat + # - edit + # - apply + + - name: gemma3 4B + model: gemma3:4b + provider: openai + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + roles: + - chat + - edit + - apply + - autocomplete + + - name: deepseek-r1 8b + model: deepseek-r1:8b + provider: openai + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + roles: + - chat + - edit + - apply + + - name: qwen3 8B + model: qwen3:8b + provider: openai + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + roles: + - chat + - edit + - apply + - autocomplete + + - name: Nomic Embed + model: nomic-embed-text:latest + provider: openai + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + embedOptions: + maxChunkSize: 8192 + roles: + - embed + + - name: Qwen 2.5b Autocomplete Model + model: qwen2.5-coder:1.5b + provider: openai + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + roles: + - chat + - edit + - apply + - autocomplete + defaultCompletionOptions: + contextLength: 32768 + maxTokens: 8192 + + - name: gpt-oss-20b + provider: openai + model: gpt-oss:20b + apiBase: ${{ secrets.OPENWEB_BASE_URL }} + apiKey: ${{ secrets.OPENWEB_API_KEY }} + roles: + - chat + - edit + - apply + + # - name: Qwen3-Coder-30B-A3B-Instruct + # provider: openai + # model: qwen3-coder:30b + # apiBase: ${{ secrets.OPENWEB_BASE_URL }} + # apiKey: ${{ secrets.OPENWEB_API_KEY }} + # roles: + # - chat + # - edit + # - apply + +context: + - provider: code + - provider: currentFile + - provider: codebase + - provider: docs + - provider: diff + - provider: file + - provider: problems + - provider: repo-map + - provider: terminal + - provider: tree diff --git a/.devcontainer/continue.env b/.devcontainer/continue.env new file mode 100644 index 0000000..b2e0433 --- /dev/null +++ b/.devcontainer/continue.env @@ -0,0 +1,2 @@ +# Open WebUI +OPENWEB_BASE_URL=http://host.containers.internal:11434/v1 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fffe73b..6eee560 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -13,7 +13,7 @@ "features": { "ghcr.io/devcontainers/features/python:1": { "installTools": true, - "toolsToInstall": "flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest,pylint,poetry,marimo[recommended]", + "toolsToInstall": "flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest,pylint,poetry,marimo[recommended],nvitop", "version": "os-provided" }, "ghcr.io/devcontainers/features/common-utils:2": { @@ -28,9 +28,10 @@ "userGid": "automatic" }, "ghcr.io/rocker-org/devcontainer-features/quarto-cli:1": { + "installTinyTex": true, + "installChromium": true, "version": "latest" }, - // R language support, https://github.com/rocker-org/devcontainer-features/tree/main/src/r-apt "ghcr.io/rocker-org/devcontainer-features/r-apt:0": { "installDevTools": true, @@ -38,8 +39,19 @@ "installRMarkdown": true, "installRadian": true, "installVscDebugger": true, + "useTesting": true, "vscodeRSupport": "full" + }, + "ghcr.io/devcontainers-extra/features/npm-packages:1": { + "package": "continuedev/cli,openai/codex,qwen-code/qwen-code", + "version": "latest" + }, + "ghcr.io/devcontainers-extra/features/apt-packages:1": { + "clean_ppas": true, + "preserve_apt_list": true, + "packages": "busybox,curl,fzf,htop,postgresql-client" } + // Example of adding R packages via apt during build: // Uncomment the following lines to install the 'curl' package for R // "features": { diff --git a/.devcontainer/vscode-init/01-install-extensions.sh b/.devcontainer/vscode-init/01-install-extensions.sh index 4ac30a2..3328bc2 100755 --- a/.devcontainer/vscode-init/01-install-extensions.sh +++ b/.devcontainer/vscode-init/01-install-extensions.sh @@ -24,7 +24,7 @@ fi echo "Installing VS Code extensions from ${EXTENSIONS_FILE}..." # Read extensions from file, remove comments and empty lines, then install all at once -extensions=$(grep -v '^#' "${EXTENSIONS_FILE}" | grep -v '^$' | tr -d '\r' | tr '\n' ' ') +extensions=$(grep -v '^#' "${EXTENSIONS_FILE}" | grep -v '^$' | tr -d '\r') if [ -z "${extensions}" ]; then echo "No extensions found in ${EXTENSIONS_FILE}" @@ -34,7 +34,7 @@ fi echo "Extensions to install: ${extensions}" # Install all extensions in a single command -"${VSCODE_SERVER_HOME}/bin/code-server" --accept-server-license-terms $(echo "${extensions}" | sed 's/[^ ]* */--install-extension &/g') +"${VSCODE_SERVER_HOME}/bin/code-server" --accept-server-license-terms $(echo "${extensions}" | sed 's/^/--install-extension /' | tr '\n' ' ') echo "VS Code extensions installation completed successfully" diff --git a/.devcontainer/vscode-init/extensions-to-download.txt b/.devcontainer/vscode-init/extensions-to-download.txt index ae18db9..2b70d1c 100644 --- a/.devcontainer/vscode-init/extensions-to-download.txt +++ b/.devcontainer/vscode-init/extensions-to-download.txt @@ -3,4 +3,10 @@ # into the user's VS Code. They will not be available in the devcontainer. # One extension ID per line. ms-vscode-remote.remote-containers -vscodevim.vim \ No newline at end of file +vscodevim.vim + +# Extensions that should be installed on the host +Continue.continue +ms-toolsai.jupyter-keymap +openai.chatgpt +REditorSupport.r-syntax \ No newline at end of file diff --git a/.devcontainer/vscode-init/extensions-to-install.txt b/.devcontainer/vscode-init/extensions-to-install.txt index feafa5f..08d66b1 100644 --- a/.devcontainer/vscode-init/extensions-to-install.txt +++ b/.devcontainer/vscode-init/extensions-to-install.txt @@ -5,11 +5,14 @@ charliermarsh.ruff Continue.continue DavidAnson.vscode-markdownlint eamodio.gitlens -marimo-team.vscode-marimo +# The marimo extension has been removed from the marketplace whilst it is being rewritten. +# marimo-team.vscode-marimo mechatroner.rainbow-csv +ms-ossdata.vscode-pgsql --pre-release ms-python.black-formatter ms-toolsai.datawrangler ms-toolsai.jupyter +openai.chatgpt REditorSupport.r REditorSupport.r-syntax yzhang.markdown-all-in-one \ No newline at end of file diff --git a/.github/workflows/build-devcontainer.yml b/.github/workflows/build-devcontainer.yml index 4829dd4..dd94917 100644 --- a/.github/workflows/build-devcontainer.yml +++ b/.github/workflows/build-devcontainer.yml @@ -10,7 +10,7 @@ on: workflow_dispatch: inputs: vscode_commit: - description: 'VS Code commit hash to use (defaults to Dockerfile ARG default if not provided)' + description: 'VS Code commit hash to use (defaults to Dockerfile declaration if not provided)' required: false type: string @@ -78,11 +78,14 @@ jobs: type=ref,event=branch type=ref,event=pr type=ref,event=tag + # Tags for default branch (main) only type=sha,prefix={{branch}}-,enable={{is_default_branch}} type=raw,value=latest,enable={{is_default_branch}} - type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }} - type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }}-{{sha}} - + type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }},enable={{is_default_branch}} + type=raw,value=vscode-${{ steps.vscode-commit.outputs.vscode_short }}-{{sha}},enable={{is_default_branch}} + # Tags for PRs only + type=ref,prefix=pr-,suffix=-${{ steps.vscode-commit.outputs.vscode_short }},event=pr + type=ref,prefix=pr-,suffix=-${{ steps.vscode-commit.outputs.vscode_short }}-{{sha}},event=pr - name: Extract tag names only id: tags run: |