From c74c7968240a457dd0380037101fd196427bd885 Mon Sep 17 00:00:00 2001 From: Alona King Date: Thu, 4 Dec 2025 13:49:59 -0500 Subject: [PATCH 1/5] Introduce missing component to trigger CI failure --- client/src/App.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/App.js b/client/src/App.js index 0a868bf..0c7126d 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,5 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import io from 'socket.io-client'; +import Missing from './Missing'; import GameHistory from './GameHistory'; // API URL - adjust if needed From 8520df43c73d0a373b4d49f12861e9d17d8385af Mon Sep 17 00:00:00 2001 From: Alona King Date: Thu, 4 Dec 2025 13:58:07 -0500 Subject: [PATCH 2/5] Fix auto-fix workflow: support repo skills without agent_context --- .github/workflows/openhands-autofix-ci.yml | 51 ++++++++++++---------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/.github/workflows/openhands-autofix-ci.yml b/.github/workflows/openhands-autofix-ci.yml index ef6de33..57615a4 100644 --- a/.github/workflows/openhands-autofix-ci.yml +++ b/.github/workflows/openhands-autofix-ci.yml @@ -117,12 +117,12 @@ jobs: from openhands.sdk import LLM, Conversation, get_logger from openhands.sdk.conversation import get_agent_final_response from openhands.sdk.utils.github import sanitize_openhands_mentions - from openhands.sdk.context.agent_context import AgentContext from openhands.sdk.context.skills import load_skills_from_dir from openhands.tools.preset.default import get_default_agent logger = get_logger(__name__) + def _load_repo_skills(repo_root: Path) -> list: """Load repo skills from .openhands/skills and legacy .openhands/microagents.""" skills: list = [] @@ -142,9 +142,26 @@ jobs: logger.error(f"Missing required env vars: {missing}") sys.exit(1) - prompt = f""" - You are fixing CI failures on PR #{os.getenv("PR_NUMBER")} in {os.getenv("REPO_NAME")}. - The PR title is: {os.getenv("PR_TITLE", "(no title)")}. + llm_model = os.getenv("LLM_MODEL") + llm_base_url = os.getenv("LLM_BASE_URL") + missing = [name for name, val in {"LLM_MODEL": llm_model, "LLM_BASE_URL": llm_base_url}.items() if not val] + if missing: + logger.error(f"Missing required env vars: {missing}") + sys.exit(1) + + repo_root = Path.cwd() + skills = _load_repo_skills(repo_root) + skills_text = "" + if skills: + logger.info(f"Loaded {len(skills)} repo skills for context") + skills_text = "\\nRepository instructions:\\n" + "\\n\\n".join( + f"- {s.name}:\\n{s.content}" for s in skills + ) + + prompt = f\"\"\" + You are fixing CI failures on PR #{os.getenv('PR_NUMBER')} in {os.getenv('REPO_NAME')}. + The PR title is: {os.getenv('PR_TITLE', '(no title)')}. + {skills_text} Goals: 1) Reproduce the failing checks locally (run the same tests/build the CI runs). @@ -153,18 +170,11 @@ jobs: 4) Leave a concise summary of what you changed. Notes: - - Branch checked out: {os.getenv("PR_HEAD_BRANCH")} - - Base branch: {os.getenv("PR_BASE_BRANCH")} + - Branch checked out: {os.getenv('PR_HEAD_BRANCH')} + - Base branch: {os.getenv('PR_BASE_BRANCH')} - If tests already pass locally, state that and exit. - Do not force-push; use the existing branch and push normally. - """ - - llm_model = os.getenv("LLM_MODEL") - llm_base_url = os.getenv("LLM_BASE_URL") - missing = [name for name, val in {"LLM_MODEL": llm_model, "LLM_BASE_URL": llm_base_url}.items() if not val] - if missing: - logger.error(f"Missing required env vars: {missing}") - sys.exit(1) + \"\"\" llm = LLM( model=llm_model, @@ -174,15 +184,7 @@ jobs: drop_params=True, ) - repo_root = Path.cwd() - skills = _load_repo_skills(repo_root) - if skills: - logger.info(f"Loaded {len(skills)} repo skills for context") - agent_context = AgentContext(skills=skills) - else: - agent_context = None - - agent = get_default_agent(llm=llm, cli_mode=True, agent_context=agent_context) + agent = get_default_agent(llm=llm, cli_mode=True) convo = Conversation(agent=agent, workspace=os.getcwd()) convo.send_message(prompt.strip()) convo.run() @@ -190,11 +192,12 @@ jobs: final = get_agent_final_response(convo.state.events) if final: final = sanitize_openhands_mentions(final) - print("\n=== Agent Summary ===\n") + print("\\n=== Agent Summary ===\\n") print(final) else: logger.warning("No final response from agent.") + if __name__ == "__main__": main() PY From 26656f9a6305e000a7a030ab50d68e779da7f579 Mon Sep 17 00:00:00 2001 From: Alona King Date: Thu, 4 Dec 2025 14:00:02 -0500 Subject: [PATCH 3/5] Fix auto-fix script block quoting and skills injection --- .github/workflows/openhands-autofix-ci.yml | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/openhands-autofix-ci.yml b/.github/workflows/openhands-autofix-ci.yml index 57615a4..48e04f6 100644 --- a/.github/workflows/openhands-autofix-ci.yml +++ b/.github/workflows/openhands-autofix-ci.yml @@ -154,27 +154,27 @@ jobs: skills_text = "" if skills: logger.info(f"Loaded {len(skills)} repo skills for context") - skills_text = "\\nRepository instructions:\\n" + "\\n\\n".join( - f"- {s.name}:\\n{s.content}" for s in skills + skills_text = "\nRepository instructions:\n" + "\n\n".join( + f"- {s.name}:\n{s.content}" for s in skills ) - prompt = f\"\"\" - You are fixing CI failures on PR #{os.getenv('PR_NUMBER')} in {os.getenv('REPO_NAME')}. - The PR title is: {os.getenv('PR_TITLE', '(no title)')}. - {skills_text} + prompt = f""" +You are fixing CI failures on PR #{os.getenv("PR_NUMBER")} in {os.getenv("REPO_NAME")}. +The PR title is: {os.getenv("PR_TITLE", "(no title)")}. +{skills_text} - Goals: - 1) Reproduce the failing checks locally (run the same tests/build the CI runs). - 2) Fix the failures. Prioritize dependency bumps and test fixes. - 3) Commit changes to the current branch (already checked out) and push if needed. - 4) Leave a concise summary of what you changed. +Goals: +1) Reproduce the failing checks locally (run the same tests/build the CI runs). +2) Fix the failures. Prioritize dependency bumps and test fixes. +3) Commit changes to the current branch (already checked out) and push if needed. +4) Leave a concise summary of what you changed. - Notes: - - Branch checked out: {os.getenv('PR_HEAD_BRANCH')} - - Base branch: {os.getenv('PR_BASE_BRANCH')} - - If tests already pass locally, state that and exit. - - Do not force-push; use the existing branch and push normally. - \"\"\" +Notes: +- Branch checked out: {os.getenv("PR_HEAD_BRANCH")} +- Base branch: {os.getenv("PR_BASE_BRANCH")} +- If tests already pass locally, state that and exit. +- Do not force-push; use the existing branch and push normally. +""" llm = LLM( model=llm_model, @@ -192,7 +192,7 @@ jobs: final = get_agent_final_response(convo.state.events) if final: final = sanitize_openhands_mentions(final) - print("\\n=== Agent Summary ===\\n") + print("\n=== Agent Summary ===\n") print(final) else: logger.warning("No final response from agent.") From 590ec40810bc0e66f3c5b9f5f35d18a2292767ca Mon Sep 17 00:00:00 2001 From: Alona King Date: Thu, 4 Dec 2025 14:02:45 -0500 Subject: [PATCH 4/5] Use AgentContext with default tools/condenser in auto-fix workflow --- .github/workflows/openhands-autofix-ci.yml | 59 +++++++++++++--------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/.github/workflows/openhands-autofix-ci.yml b/.github/workflows/openhands-autofix-ci.yml index 48e04f6..86a8f5e 100644 --- a/.github/workflows/openhands-autofix-ci.yml +++ b/.github/workflows/openhands-autofix-ci.yml @@ -114,11 +114,15 @@ jobs: import os import sys from pathlib import Path - from openhands.sdk import LLM, Conversation, get_logger + from openhands.sdk import Agent, LLM, Conversation, get_logger from openhands.sdk.conversation import get_agent_final_response from openhands.sdk.utils.github import sanitize_openhands_mentions + from openhands.sdk.context.agent_context import AgentContext from openhands.sdk.context.skills import load_skills_from_dir - from openhands.tools.preset.default import get_default_agent + from openhands.tools.preset.default import ( + get_default_tools, + get_default_condenser, + ) logger = get_logger(__name__) @@ -151,17 +155,36 @@ jobs: repo_root = Path.cwd() skills = _load_repo_skills(repo_root) - skills_text = "" - if skills: - logger.info(f"Loaded {len(skills)} repo skills for context") - skills_text = "\nRepository instructions:\n" + "\n\n".join( - f"- {s.name}:\n{s.content}" for s in skills - ) + agent_context = AgentContext(skills=skills) if skills else None + + llm = LLM( + model=llm_model, + api_key=os.getenv("LLM_API_KEY"), + base_url=llm_base_url, + usage_id="ci_autofix_agent", + drop_params=True, + ) + + tools = get_default_tools(enable_browser=False) + condenser = get_default_condenser( + llm.model_copy(update={"usage_id": "condenser"}) + ) + + agent_kwargs = dict( + llm=llm, + tools=tools, + system_prompt_kwargs={"cli_mode": True}, + condenser=condenser, + ) + if agent_context: + agent_kwargs["agent_context"] = agent_context + + agent = Agent(**agent_kwargs) + convo = Conversation(agent=agent, workspace=os.getcwd()) prompt = f""" -You are fixing CI failures on PR #{os.getenv("PR_NUMBER")} in {os.getenv("REPO_NAME")}. -The PR title is: {os.getenv("PR_TITLE", "(no title)")}. -{skills_text} +You are fixing CI failures on PR #{os.getenv('PR_NUMBER')} in {os.getenv('REPO_NAME')}. +The PR title is: {os.getenv('PR_TITLE', '(no title)')}. Goals: 1) Reproduce the failing checks locally (run the same tests/build the CI runs). @@ -170,22 +193,12 @@ Goals: 4) Leave a concise summary of what you changed. Notes: -- Branch checked out: {os.getenv("PR_HEAD_BRANCH")} -- Base branch: {os.getenv("PR_BASE_BRANCH")} +- Branch checked out: {os.getenv('PR_HEAD_BRANCH')} +- Base branch: {os.getenv('PR_BASE_BRANCH')} - If tests already pass locally, state that and exit. - Do not force-push; use the existing branch and push normally. """ - llm = LLM( - model=llm_model, - api_key=os.getenv("LLM_API_KEY"), - base_url=llm_base_url, - usage_id="ci_autofix_agent", - drop_params=True, - ) - - agent = get_default_agent(llm=llm, cli_mode=True) - convo = Conversation(agent=agent, workspace=os.getcwd()) convo.send_message(prompt.strip()) convo.run() From c1e611d1a94b93a89ed7419211c9b9ff73b867bd Mon Sep 17 00:00:00 2001 From: OpenHands Agent Date: Thu, 4 Dec 2025 19:20:37 +0000 Subject: [PATCH 5/5] fix(ci): remove stray import of './Missing' to restore client build in CI The CI build failed because client/src/App.js imported a non-existent module './Missing'. This removes that import. Local reproduction: npm run install-all && npm run build. Co-authored-by: openhands --- client/src/App.js | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/App.js b/client/src/App.js index 0c7126d..0a868bf 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,6 +1,5 @@ import React, { useState, useEffect, useRef } from 'react'; import io from 'socket.io-client'; -import Missing from './Missing'; import GameHistory from './GameHistory'; // API URL - adjust if needed