Documentation
¶
Overview ¶
Package applypatch applies the patches that OpenAI models write with the apply_patch tool, to strings in memory.
Two formats are supported. An update diff (V4A) edits one text, as in the diff of a Responses API apply_patch update_file operation:
@@ def greet():
- print("Hi")
+ print("Hello")
A patch, as written for the Codex apply_patch tool (see CodexTool), wraps operations on several files:
*** Begin Patch
*** Add File: hello.txt
+Hello
*** Update File: greet.py
@@ def greet():
- print("Hi")
+ print("Hello")
*** End Patch
A Mode decides how update diffs are matched. Strict, the default, never guesses: anchors, context, and removed lines must match byte for byte and exactly once. Codex follows the Codex CLI: first match, then fuzzy fallbacks for whitespace and Unicode punctuation.
Strict mode is a Go port of applyDiff from the OpenAI Agents SDK for JavaScript (MIT). Codex mode, the patch parser, and CodexTool are a Go port of apply_patch from OpenAI Codex (Apache-2.0).
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply applies one update diff to input in Strict mode.
Example ¶
package main
import (
"fmt"
"github.com/fgn/applypatch"
)
func main() {
input := "def greet():\n print(\"Hi\")\n"
diff := "@@ def greet():\n- print(\"Hi\")\n+ print(\"Hello\")"
output, err := applypatch.Apply(input, diff)
if err != nil {
fmt.Println(err)
return
}
fmt.Print(output)
}
Output: def greet(): print("Hello")
func ApplyBatch ¶
ApplyBatch applies several update diffs to input in Strict mode.
Example ¶
package main
import (
"fmt"
"github.com/fgn/applypatch"
)
func main() {
input := "alpha\nbeta\ngamma\n"
output, err := applypatch.ApplyBatch(input, []string{"-alpha\n+ALPHA", "-gamma\n+GAMMA"})
if err != nil {
fmt.Println(err)
return
}
fmt.Print(output)
}
Output: ALPHA beta GAMMA
func ApplyFiles ¶
ApplyFiles applies an apply_patch patch to files in Strict mode.
Example ¶
package main
import (
"fmt"
"github.com/fgn/applypatch"
)
func main() {
files := map[string]string{"greet.py": "print(\"Hi\")\n"}
patch := `*** Begin Patch
*** Add File: README.md
+# Greeter
*** Update File: greet.py
@@
-print("Hi")
+print("Hello")
*** End Patch`
output, err := applypatch.Codex.ApplyFiles(files, patch)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%q\n%q\n", output["README.md"], output["greet.py"])
}
Output: "# Greeter\n" "print(\"Hello\")\n"
Types ¶
type Mode ¶
type Mode int
Mode selects how update diffs are parsed and matched against the text they patch. The zero value is Strict.
const ( // Strict applies an update diff only when every anchor, context line, and // removed line matches the input byte for byte and exactly once. It never // guesses: a diff that could apply in more than one place is an error. Strict Mode = iota // Codex applies patches the way the apply_patch tool of the OpenAI Codex // CLI does with line-ending preservation enabled. It takes the first // match, falls back to ignoring whitespace and Unicode punctuation // differences, appends insertions without context to the end of the file, // keeps each line's ending, and ends every line with a newline. Codex )
func (Mode) Apply ¶
Apply applies one update diff to input and returns the patched text. The diff is the V4A body of an update, as in the diff of an apply_patch update_file operation, without "*** Update File:" or other patch headers. A final "\n" ends the last line rather than adding an empty one. Strict mode also accepts "\r\n" line breaks; Codex mode splits on "\n" only and keeps any "\r" as part of the line.
Example ¶
package main
import (
"fmt"
"github.com/fgn/applypatch"
)
func main() {
// Strict mode rejects a diff that only matches when whitespace is
// ignored; Codex mode applies it like the Codex CLI would.
input := "total \n"
diff := "-total\n+sum"
_, err := applypatch.Strict.Apply(input, diff)
fmt.Println("strict:", err)
output, _ := applypatch.Codex.Apply(input, diff)
fmt.Printf("codex: %q\n", output)
}
Output: strict: target must match exactly once codex: "sum\n"
func (Mode) ApplyBatch ¶
ApplyBatch applies several update diffs to input. In Strict mode every diff targets the original input and overlapping edits fail the whole batch. In Codex mode the diffs apply one after another, like consecutive apply_patch calls on the same file.
func (Mode) ApplyFiles ¶
ApplyFiles applies an apply_patch patch, "*** Begin Patch" through "*** End Patch", to files, a map from path to contents. It returns a new map and leaves files unchanged. Paths are map keys used exactly as written in the patch. Operations apply in order, and if any fails, ApplyFiles returns only the error.
type Operation ¶
type Operation struct {
Kind OperationKind
Path string
// MoveTo is the new path of an updated file, or empty.
MoveTo string
// Contents is the text of an added file: each "+" line of the patch
// followed by a newline.
Contents string
// Diff is the update diff of an updated file: each line of the patch
// followed by "\n". Mode.Apply(contents, Diff) applies it exactly as
// ApplyFiles would.
Diff string
}
Operation is one file operation of a patch.
type OperationKind ¶
type OperationKind int
OperationKind says what an Operation does to its file.
const ( // AddFile creates a file, replacing any file at the same path. AddFile OperationKind = iota + 1 // DeleteFile removes an existing file. DeleteFile // UpdateFile applies an update diff to an existing file and can move it. UpdateFile )
func (OperationKind) String ¶
func (k OperationKind) String() string
String returns "add", "delete", or "update".
type Patch ¶
type Patch struct {
// EnvironmentID is the value of an optional "*** Environment ID:" line.
EnvironmentID string
Operations []Operation
}
Patch is a parsed apply_patch patch.
type Tool ¶
type Tool struct {
Type string `json:"type"`
Name string `json:"name"`
Description string `json:"description"`
Format ToolFormat `json:"format"`
}
Tool is a custom (freeform) tool definition for the OpenAI Responses API.
func CodexTool ¶
func CodexTool() Tool
CodexTool returns the apply_patch tool that Codex gives GPT-5 models: a custom tool whose input must match a Lark grammar for the "*** Begin Patch" format. Pass the input of the model's custom_tool_call to Mode.ApplyFiles.
Example ¶
package main
import (
"fmt"
"github.com/fgn/applypatch"
)
func main() {
tool := applypatch.CodexTool()
fmt.Println(tool.Type, tool.Name, tool.Format.Type, tool.Format.Syntax)
}
Output: custom apply_patch grammar lark
type ToolFormat ¶
type ToolFormat struct {
Type string `json:"type"`
Syntax string `json:"syntax"`
Definition string `json:"definition"`
}
ToolFormat constrains the input of a custom tool.