-
Notifications
You must be signed in to change notification settings - Fork 100
feat(tools): Add GPT-5.1 ApplyPatch tool #1166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 35 commits
9d2442a
c5a0836
fc86fa7
3c429e1
772ce28
f08a048
9ae743f
02e67d3
a00128b
35e3be3
e910dbf
6cd9639
e772cbb
0149040
e8978ad
73f7f81
fab4f3b
db5b177
74f0d15
a7eed40
d1ce8f3
3078a95
8691cec
1f7e0af
f4c54d2
dd6c7df
9dff45e
99213f1
e59b3c4
76c21e3
7fa1aab
6c89fd4
5d99105
53f0301
24da42f
9362ad9
bd4d338
a0e1070
adcb46d
be8e7c7
adffe6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| """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), | ||
| native_tool_calling=True, # enable native tool calling (Responses API) | ||
enyst marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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}") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from .definition import ApplyPatchTool | ||
|
|
||
|
|
||
| __all__ = ["ApplyPatchTool"] |
Uh oh!
There was an error while loading. Please reload this page.