diff --git a/.github/workflows/weekly-architecture-refresh.yml b/.github/workflows/weekly-architecture-refresh.yml new file mode 100644 index 00000000..9e77badd --- /dev/null +++ b/.github/workflows/weekly-architecture-refresh.yml @@ -0,0 +1,41 @@ +name: Weekly architecture docs refresh + +on: + schedule: + - cron: '0 7 * * 1' # Mondays 07:00 UTC + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + refresh-architecture: + runs-on: ubuntu-latest + if: github.actor != 'github-actions[bot]' + env: + OPENHANDS_API_KEY: ${{ secrets.OPENHANDS_API_KEY }} + steps: + - name: Checkout docs repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Install dependencies + run: | + uv pip install requests + + - name: Run OpenHands conversation to refresh architecture docs + run: | + uv run --python 3.12 python scripts/openhands_api.py \ + --prompt scripts/prompts/architecture_refresh.j2 \ + --repo OpenHands/docs \ + --base-url https://app.all-hands.dev + + - name: Log follow-up + run: | + echo "If the agent proposed changes, it will open a PR titled 'docs: weekly architecture docs refresh'." + echo "Otherwise, it will comment that no updates are needed." diff --git a/scripts/openhands_api.py b/scripts/openhands_api.py new file mode 100644 index 00000000..860a77a5 --- /dev/null +++ b/scripts/openhands_api.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +""" +Minimal helper to invoke the OpenHands Cloud API to start a conversation +for weekly documentation automation tasks. + +Environment: +- OPENHANDS_API_KEY: required. Cloud API key created at https://app.all-hands.dev/settings/api-keys + +Usage: + python scripts/openhands_api.py \ + --prompt scripts/prompts/architecture_refresh.j2 \ + --repo OpenHands/docs \ + [--base-url https://app.all-hands.dev] + +Notes: +- This helper only creates the conversation and prints its URL. The remote + agent is expected to open any PRs. +""" +from __future__ import annotations + +import argparse +import os +import sys +from dataclasses import dataclass +from typing import Any + +import requests + + +DEFAULT_BASE_URL = "https://app.all-hands.dev" +API_TIMEOUT = 30 # seconds + + +@dataclass +class Conversation: + id: str + status: str | None + + +def create_conversation(base_url: str, api_key: str, initial_user_msg: str, repo: str | None = None) -> Conversation: + url = base_url.rstrip("/") + "/api/conversations" + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json", + "Accept": "application/json", + } + payload: dict[str, Any] = {"initial_user_msg": initial_user_msg} + if repo: + payload["repository"] = repo + with requests.Session() as s: + s.headers.update(headers) + r = s.post(url, json=payload, timeout=API_TIMEOUT) + r.raise_for_status() + data = r.json() + conv_id = data.get("conversation_id") or data.get("id") or "" + status = data.get("status") + if not conv_id: + raise RuntimeError(f"Unexpected response creating conversation: {data}") + return Conversation(id=str(conv_id), status=status) + + +def read_text(path: str) -> str: + with open(path, "r", encoding="utf-8") as f: + return f.read() + + +def build_prompt(prompt_file: str) -> str: + return read_text(prompt_file) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--prompt", required=True, help="Path to prompt file (j2 or txt)") + parser.add_argument("--repo", required=False, help="Target GitHub repo for the agent to work on, e.g. OpenHands/docs") + parser.add_argument("--base-url", default=DEFAULT_BASE_URL, help="OpenHands API base URL") + args = parser.parse_args() + + api_key = os.getenv("OPENHANDS_API_KEY") + if not api_key: + print("ERROR: OPENHANDS_API_KEY is not set.", file=sys.stderr) + return 2 + + try: + initial_user_msg = build_prompt(args.prompt) + except Exception as e: + print(f"ERROR: failed to read prompt: {e}", file=sys.stderr) + return 2 + + try: + conv = create_conversation(args.base_url, api_key, initial_user_msg, repo=args.repo) + except Exception as e: + print(f"ERROR: failed to create conversation: {e}", file=sys.stderr) + return 1 + + conv_url = args.base_url.rstrip("/") + f"/conversations/{conv.id}" + print(f"Created conversation: {conv.id}") + print(f"URL: {conv_url}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/prompts/architecture_refresh.j2 b/scripts/prompts/architecture_refresh.j2 new file mode 100644 index 00000000..3983a625 --- /dev/null +++ b/scripts/prompts/architecture_refresh.j2 @@ -0,0 +1,41 @@ +You are OpenHands, operating via the OpenHands Cloud API. Your task is to refresh the weekly SDK architecture documentation in the OpenHands/docs repository under sdk/arch. + +Scope and goals: +- Review the current architecture docs in this repo under sdk/arch for OpenHands V1 (software-agent-sdk and agent server). +- Compare against the latest code in: + - https://github.com/OpenHands/software-agent-sdk (this repo contains the SDK and the agent-server package: openhands-agent-server/) +- If substantive differences or missing sections are found, prepare updated pages and open a PR to OpenHands/docs. + +Style and factuality requirements: + +Do not invent behavior; verify every statement against repository code or existing docs. +Cite sources inline using Markdown links to GitHub source files with short context, e.g., [api.py](https://github.com/OpenHands/software-agent-sdk/blob/HEAD/openhands-agent-server/openhands/agent_server/api.py). +Keep tone clear, concise, and neutral. +Prefer Mermaid diagrams for flows, classes, and sequences. +Include a Last updated timestamp and Source commit (git rev-parse HEAD) at the bottom of each page. + +Pull Request requirements: + +If you propose changes compared to the previous week, open a PR yourself. +Read and follow .github/pull_request_template.md. +Title: "docs: weekly architecture docs refresh". +Body: summarize updated/added pages and major changes; list sources cited. +Run pre-commit hooks and ensure CI passes. + +Documentation framework requirements: +- Follow the Guide for Writing Architecture Component Documentation included in this repo (docs/.openhands/microagents/sdk-guidelines.md) for structure and length. +- Prioritize these pages if updates are needed: overview.mdx, agent.mdx, conversation.mdx, llm.mdx, tool-system.mdx, workspace.mdx, agent-server.mdx, events.mdx, condenser.mdx, security.mdx. +- Ensure diagrams are simple and consistent (Mermaid, max ~12 nodes, consistent styles as in the guide). +- Use inline GitHub links to source files for every component mentioned in tables. + + +Operational constraints: +- Work only within architecture docs (sdk/arch). Do not modify guides or API reference unless strictly necessary for correctness. +- Keep changes focused and minimal. +- If no changes are necessary, post a short comment in the conversation stating no updates needed this week with a summary of checks performed. + +Output format for proposed changes: +- For each updated page: a succinct summary of what changed, and the list of sources with inline citations. +- Use GitHub-flavored Markdown compatible with our Mintlify setup. + +Begin by auditing the current sdk/arch pages versus HEAD of the software-agent-sdk repository. Then either open a PR with updates or state that no changes are required.