diff --git a/docs.json b/docs.json index 4b4e0853..52b6844a 100644 --- a/docs.json +++ b/docs.json @@ -223,7 +223,8 @@ "sdk/guides/agent-browser-use", "sdk/guides/agent-custom", "sdk/guides/convo-custom-visualizer", - "sdk/guides/agent-stuck-detector" + "sdk/guides/agent-stuck-detector", + "sdk/guides/agent-apply-patch-gpt5-1" ] }, { @@ -505,4 +506,4 @@ "destination": "/overview/skills/public" } ] -} \ No newline at end of file +} diff --git a/sdk/guides/agent-apply-patch-gpt5-1.mdx b/sdk/guides/agent-apply-patch-gpt5-1.mdx new file mode 100644 index 00000000..e93abae6 --- /dev/null +++ b/sdk/guides/agent-apply-patch-gpt5-1.mdx @@ -0,0 +1,138 @@ +--- +title: ApplyPatch with GPT-5.1 +description: Use the GPT-5.1 apply_patch tool format to perform rich multi-file edits via the ApplyPatch tool. +--- + + +This guide shows how to use the `ApplyPatch` tool with GPT-5.1 models using the `apply_patch` text format introduced in the OpenAI cookbook. The tool lets the model propose unified patches that can: + +- Create new files +- Apply multi-hunk edits to a single file +- Touch multiple files in a single patch +- Mix add / update / delete operations safely + +The SDK wires this up as a normal tool, so you can run it inside an `Agent` and `Conversation` like any other tool. + +## Example + +```python icon="python" expandable +"""Example: Using ApplyPatch tool with GPT-5.1 models via direct OpenAI API. + +This demonstrates adding the ApplyPatch tool to the agent and guiding the +model through a richer sequence of file operations using 'apply_patch' text: + +- Create multiple files (FACTS.txt, NOTES.md) +- Apply multi-hunk edits to a single file +- Apply a single patch that touches multiple files +- Mix add / update / delete operations in one patch + +Notes: +- Works with any GPT-5.1 family model (names start with "gpt-5.1"). +- Uses direct OpenAI API through LiteLLM's LLM wrapper with no base_url. +- Requires OPENAI_API_KEY in the environment (or LLM_API_KEY fallback). +""" + +from __future__ import annotations + +import os + +from pydantic import SecretStr + +from openhands.sdk import LLM, Agent, Conversation, get_logger +from openhands.sdk.tool import Tool +from openhands.tools.apply_patch import ApplyPatchTool +from openhands.tools.task_tracker import TaskTrackerTool + +# from openhands.tools.preset.default import register_default_tools +from openhands.tools.terminal import TerminalTool + + +logger = get_logger(__name__) + +api_key = os.getenv("OPENAI_API_KEY") or os.getenv("LLM_API_KEY") +assert api_key, "Set OPENAI_API_KEY (or LLM_API_KEY) in your environment." + +# Choose a GPT-5.1 model; mini is cost-effective for examples +default_model = "openai/gpt-5.1-codex-mini" +model = os.getenv("LLM_MODEL", default_model) +assert model.startswith("openai/gpt-5.1"), "Model must be an openai gpt-5.1 variant" + +llm = LLM( + model=model, + api_key=SecretStr(api_key), + reasoning_summary=None, # avoid OpenAI org verification requirement + log_completions=True, # enable telemetry to log input/output payloads +) + +# Explicitly register tool classes so Tool(name=...) can resolve +# They self-register into the global registry on import +_ = (TerminalTool, TaskTrackerTool, ApplyPatchTool) + +agent = Agent( + llm=llm, + tools=[ + Tool(name="terminal"), + Tool(name="task_tracker"), + Tool(name="apply_patch"), + ], + system_prompt_kwargs={"cli_mode": True}, +) + +conversation = Conversation(agent=agent, workspace=os.getcwd()) + +# Compose instructions guiding the model to exercise richer ApplyPatch behavior. +prompt = ( + "You have access to an apply_patch tool that edits files using unified patches. " + "Use it to perform the following sequence of operations in as few patches as " + "reasonable, while keeping each patch valid and focused:\n\n" + "1) Create two files:\n" + " - FACTS.txt containing exactly two lines:\n" + " OpenHands SDK integrates tools.\n" + " ApplyPatch can edit multiple files.\n" + " - NOTES.md containing exactly three lines:\n" + " # Notes\n" + " - Initial point A\n" + " - Initial point B\n\n" + "2) Apply a multi-hunk update to NOTES.md in a single *** Update File block:\n" + " - Change the text 'Initial point A' to 'Updated point A'.\n" + " - Append a new bullet '- Added via multi-hunk patch.' after " + "'Initial point B'.\n\n" + "3) Apply a single patch that updates BOTH FACTS.txt and NOTES.md at once:\n" + " - In FACTS.txt, append a third line: 'Multi-file patches are supported.'.\n" + " - In NOTES.md, append a final line: 'Summary: multi-file patch applied.'.\n\n" + "4) Finally, use one more patch that mixes operations across files:\n" + " - Add a TEMP.txt file containing a single line: 'Temporary file'.\n" + " - Append a line 'Cleanup step ran.' to FACTS.txt.\n" + " - Delete TEMP.txt.\n\n" + "Important rules:\n" + "- Only call the tool using the apply_patch text format between " + "'*** Begin Patch' and '*** End Patch'.\n" + "- Use '*** Add File', '*** Update File', and '*** Delete File' sections as " + "described in the GPT-5.1 apply_patch guide.\n" + "- When updating a file, include enough context lines so the patch can be " + "applied even if whitespace varies slightly.\n" +) + +conversation.send_message(prompt) +conversation.run() + +print("Conversation finished.") +print(f"EXAMPLE_COST: {llm.metrics.accumulated_cost}") +``` + +```bash Running the Script +export OPENAI_API_KEY="your-openai-api-key" +# or: export LLM_API_KEY="your-openai-api-key" +uv run python apply_patch_with_gpt5_1.py +``` + +## How It Works + +The example wires the `ApplyPatch` tool into an `Agent` alongside `terminal` and `task_tracker`, then guides a GPT-5.1 model through a sequence of increasingly complex patch operations: + +1. **Create files**: The model uses `*** Add File` blocks to create `FACTS.txt` and `NOTES.md` with precise contents. +2. **Multi-hunk update**: A single `*** Update File` block performs multiple edits in `NOTES.md`, demonstrating multi-hunk patches. +3. **Multi-file patch**: One patch updates both `FACTS.txt` and `NOTES.md` together, showing how a single patch can touch multiple files. +4. **Mixed operations**: The final patch adds `TEMP.txt`, appends to `FACTS.txt`, and then deletes `TEMP.txt`, exercising add/update/delete in one go. + +All edits are proposed in the GPT-5.1 `apply_patch` text format and executed by the `ApplyPatch` tool inside the workspace.