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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// For format details, see https://aka.ms/devcontainer.json.
{
"name": "Reboot Devcontainer",
"image": "ghcr.io/reboot-dev/reboot-devcontainer",
"remoteUser": "dev",

"customizations": {
"vscode": {
// The following VS Code extensions are nice to have when developing on
// this Reboot application.
"extensions": [
// Python support.
"ms-python.python",
// Static type checking for Python.
"ms-python.mypy-type-checker",
// YAPF code formatter for Python.
"eeyore.yapf",
// Automatic import sorting for Python.
"ms-python.isort",
// Protocol buffer support.
"zxh404.vscode-proto3",
// Prettier code formatter.
"esbenp.prettier-vscode"
]
}
},

// Ports from the devcontainer made available on your local machine.
"forwardPorts": [
// The HTTP port exposed by default in examples.
3000,
// The gRPC backend port exposed by default in examples.
9991
]
}
39 changes: 39 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Python runtime caches and venv — rebuilt inside the image.
.venv/
__pycache__/
*.py[cod]
.mypy_cache/
.pytest_cache/

# Reboot runtime state (dev-only).
.rbt/

# Generated code — regenerated inside the image by `rbt
# generate`.
backend/api/
web/api/

# Node sources / deps / caches — we only copy `web/dist/`
# into the image.
web/node_modules/
web/ui/
web/src/
web/package.json
web/package-lock.json
web/tsconfig*.json
web/vite.config.ts
web/index.css

# VCS.
.git/
.gitignore

# Editor / OS.
.vscode/
.idea/
*.swp
.DS_Store

# Local-only files.
mcp_servers.json
README.md
47 changes: 47 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Test

on:
push:
# Run CI (only) on our main branch to show that it is always in a green
# state. Don't run it on other branches; if a developer cares about one
# of the non-main branches they'll run tests manually or open a PR.
branches:
- "main"
pull_request:
# Run CI on pull requests. Passing checks will be required to merge.
branches:
- "**"
merge_group:
# Required if we want to use GitHub's Merge Queue feature. See:
# https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue#triggering-merge-group-checks-with-github-actions

concurrency:
# Have at most one of these workflows running per branch, cancelling older
# runs that haven't completed yet when they become obsolete.
#
# When pushing new commits to a PR, each one of those commits triggers a new
# workflow run that would normally run to completion, even when subsequent
# pushes to the PR make their result obsolete. This consumes resources for no
# benefit. We override that default behavior to save resources, cancelling any
# older still-running workflows when a new workflow starts
#
# See documentation about the `github` context variables here:
# https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
group: ${{ github.workflow }}-${{ github.ref }}
# Do not cancel runs on the main branch. On the main branch we want every
# commit to be tested.
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
backend-test:
name: Backend test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: pytest (in Dev Container)
uses: devcontainers/ci@v0.3
with:
runCmd: |
.tests/test.sh
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Python virtual environment.
.venv/

# Byte-compiled files.
__pycache__/
*.py[cod]
*$py.class

# Generated API code (from `rbt generate`).
backend/api/
web/api/

# Reboot runtime state.
.rbt/

# Distribution / packaging.
*.egg-info/

# mypy / pytest caches.
.mypy_cache/
.pytest_cache/

# Node / web build artifacts.
web/node_modules/
web/dist/

# IDE / editor.
.idea/
.vscode/
*.swp

# OS.
.DS_Store
32 changes: 32 additions & 0 deletions .mergequeue/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: 1.0.0
merge_rules:
publish_status_check: true
labels:
trigger: mergequeue-ready
skip_line: ""
merge_failed: ""
skip_delete_branch: ""
update_latest: true
delete_branch: false
use_rebase: true
enable_comments: true
ci_timeout_mins: 0
preconditions:
number_of_approvals: 1
use_github_mergeability: true
conversation_resolution_required: true
merge_mode:
type: default
parallel_mode: null
auto_update:
enabled: false
label: ""
max_runs_for_update: 0
merge_commit:
use_title_and_body: false
merge_strategy:
name: squash
override_labels:
squash: ""
merge: ""
rebase: mergequeue-rebase
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10.13
49 changes: 49 additions & 0 deletions .rbtrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Find API definitions in 'api/'.
generate api/

# Tell `rbt generate` where to put generated files.
generate --python=backend/api/

# Generate React bindings for web apps (into "web/api/").
generate --react=web/api
generate --react-extensions

# Watch if any source files are modified.
dev run --watch=backend/**/*.py

# Tell `rbt` that this is a Python application.
dev run --python

# Save state between restarts.
dev run --application-name=agent-wiki

# Run the application!
dev run --application=backend/src/main.py

# Default to HMR mode when no --config is specified.
dev run --default-config=hmr

# Hot Module Replacement (HMR): Vite dev server proxied through Envoy.
# Run Vite in a separate terminal: cd web && npm run dev
# Envoy routes "/__/web/**" to Vite for HMR support.
dev run:hmr --mcp-frontend-host=http://localhost:4444

# Dist mode: serve pre-built artifacts from "web/dist/" (no Vite HMR).
# Usage: uv run rbt dev run --config=dist
# Requires: cd web && npm run build
dev run:dist --mcp-frontend-host=""

# When expunging, expunge that state we've saved.
dev expunge --application-name=agent-wiki

# Production (`rbt serve run`) settings, used by the Dockerfile
# when deploying to the Reboot Cloud. In production `web/dist/`
# is served from disk, so no `--mcp-frontend-host` is needed
# (that flag is dev-only anyway).
serve run --python
serve run --application-name=agent-wiki
serve run --application=backend/src/main.py

# Leave TLS termination to the external load balancer; expose
# a non-SSL port to that load balancer.
serve run --tls=external
99 changes: 99 additions & 0 deletions .tests/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash

set -e # Exit if a command exits with an error.
set -x # Echo executed commands to help debug failures.

# MacOS tests can fail due to a race in `protoc` writing files to
# disk, so now we check only occurrences of the expected lines in
# the output. See https://github.com/reboot-dev/mono/issues/3433
check_lines_in_file() {
local expected="$1"
local actual="$2"

while IFS= read -r line; do
if ! grep -Fxq "$line" "$actual"; then
echo "Line $line is missing in the actual output."
exit 1
fi
done < "$expected"
}

# Use the published Reboot pip package by default, but allow the
# test system to override it with a different value.
if [ -n "$REBOOT_WHL_FILE" ]; then
# Install the `reboot` package from the specified path
# explicitly, overwriting the version from `pyproject.toml`.
rye remove --no-sync reboot
rye remove --no-sync --dev reboot
rye add --dev reboot --absolute --path="${SANDBOX_ROOT}$REBOOT_WHL_FILE"
fi

# Force a fresh virtualenv. A pre-existing `.venv/` (e.g.,
# carried over from a pre-baked image, or copied between
# containers/host paths during the dev-container test) will
# have absolute shebangs in its console scripts (`rbt`,
# `pytest`) pointing at the path where it was originally
# created, which produces "bad interpreter: No such file or
# directory" when those scripts are executed from a different
# location. `rye sync` only regenerates entry-point scripts
# for packages it reinstalls, so it can't repair an existing
# venv whose shebangs are stale. Nuking and re-syncing here
# guarantees the venv lives at the current path.
rm -rf .venv
rye sync --no-lock

# Don't `source .venv/bin/activate`: that script bakes in the
# venv's original creation path on its first line, which is
# wrong when the venv has been relocated (e.g., a pre-baked
# image bind-mounted at a different path in CI). The
# console-script wrappers (`rbt`, `pytest`) also have absolute
# shebangs that point at the stale path. Set `PATH` and
# `VIRTUAL_ENV` to the real location ourselves, and invoke the
# tools via `python -m`: the `python` symlink resolves the
# venv from its own location through `pyvenv.cfg`, so it
# survives relocation, and `-m` bypasses the broken script
# shebangs.
VENV_BIN="$(pwd)/.venv/bin"
export PATH="$VENV_BIN:$PATH"
export VIRTUAL_ENV="$(pwd)/.venv"
PYTHON="$VENV_BIN/python"

# When running in a Bazel test, our `.rbtrc` file ends up in a
# very deep directory structure, which can result in "path too
# long" errors from RocksDB. Explicitly specify a shorter path.
RBT_FLAGS="--state-directory=$(mktemp -d)"

"$PYTHON" -m reboot.cli.rbt_main $RBT_FLAGS generate

"$PYTHON" -m pytest backend/

if [ -n "$EXPECTED_RBT_DEV_OUTPUT_FILE" ]; then
actual_output_file=$(mktemp)

# `--config=dist` overrides `.rbtrc`'s default `hmr` config,
# whose `--mcp-frontend-host=http://localhost:4444` would
# have Envoy proxy `/__/web/**` to a Vite dev server. There
# is no Vite running in CI, and on the macOS executable-Envoy
# path that proxy target makes cluster init hang
# indefinitely, so `--terminate-after-health-check` never
# fires. The `dist` config sets `--mcp-frontend-host=""`,
# which skips the proxy entirely. `web/dist/` doesn't need
# to actually exist; the health check only probes gRPC and
# Envoy listeners.
#
# The librarian agent fails fast if `ANTHROPIC_API_KEY` is
# unset, so we provide a dummy value. No real Anthropic calls
# are made: the health check terminates the process before any
# transcript ingestion happens.
ANTHROPIC_API_KEY="dummy-for-health-check" \
"$PYTHON" -m reboot.cli.rbt_main $RBT_FLAGS dev run \
--config=dist \
--terminate-after-health-check \
> "$actual_output_file"

check_lines_in_file \
"${SANDBOX_ROOT}$EXPECTED_RBT_DEV_OUTPUT_FILE" \
"$actual_output_file"

rm "$actual_output_file"
fi
24 changes: 24 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This `BUILD.bazel` file allows a `bazel` system (configured outside of
# this repository) to use code in this directory and its subdirectories.

filegroup(
name = "everything",
srcs = glob(
["**/*"],
exclude = [
# Files that may be created by activity in this directory,
# such as manually following the steps of the `README.md`
# file, but which are not part of the "source code" of this
# repository.
".venv/**/*",
".rbt/**/*",
".pytest_cache/**/*",
".mypy_cache/**/*",
"backend/api/**/*",
"web/api/**/*",
"web/node_modules/**/*",
"web/dist/**/*",
],
),
visibility = ["//visibility:public"],
)
Loading
Loading