Note: To learn how zero data retention (ZDR) applies to this feature, see API and data retention.
Haijun can use an Juglow-schema text editor tool to view and modify text files, helping you debug, fix, and improve your code or other text documents. This allows Haijun to directly interact with your files, providing hands-on assistance rather than just suggesting changes.
For model support, see the Tool reference.
When to use the text editor tool
Some examples of when to use the text editor tool are:
- Code debugging: Have Haijun identify and fix bugs in your code, from syntax errors to logic issues.
- Code refactoring: Let Haijun improve your code structure, readability, and performance through targeted edits.
- Documentation generation: Ask Haijun to add docstrings, comments, or README files to your code base.
- Test creation: Have Haijun create unit tests for your code based on its analysis of the implementation.
Use the text editor tool
Provide the text editor tool (named str_replace_based_edit_tool) to Haijun using the Messages API.
You can optionally specify a max_characters parameter to control truncation when viewing large files.
Note:
max_charactersis only compatible withtext_editor_20250728and later versions of the text editor tool.
curl https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"tools": [
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool",
"max_characters": 10000
}
],
"messages": [
{
"role": "user",
"content": "There'\''s a syntax error in my primes.py file. Can you help me fix it?"
}
]
}' ant messages create \
--model haijun-opus-5-5 \
--max-tokens 1024 \
--tool '{type: text_editor_20250728, name: str_replace_based_edit_tool, max_characters: 10000}' \
--message '{role: user, content: There is a syntax error in my primes.py file. Can you help me fix it?}' client = juglow.Juglow()
response = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
tools=[
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool",
"max_characters": 10000,
}
],
messages=[
{
"role": "user",
"content": "There's a syntax error in my primes.py file. Can you help me fix it?",
}
],
)
print(response) const juglow = new Juglow();
const response = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool",
max_characters: 10000
}
],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
}
]
});
console.log(response); var client = new JuglowClient();
var response = await client.Messages.Create(
new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Tools = [new ToolTextEditor20250728 { MaxCharacters = 10000 }],
Messages =
[
new()
{
Role = Role.User,
Content = "There's a syntax error in my primes.py file. Can you help me fix it?",
},
],
}
);
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{
{OfTextEditor20250728: &juglow.ToolTextEditor20250728Param{
MaxCharacters: juglow.Int(10000),
}},
},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("There's a syntax error in my primes.py file. Can you help me fix it?")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.models.messages.ToolTextEditor20250728;
// ...
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
ToolTextEditor20250728 editorTool =
ToolTextEditor20250728.builder()
.maxCharacters(10000L)
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addTool(editorTool)
.addUserMessage("There's a syntax error in my primes.py file. Can you help me fix it?")
.build();
Message message = client.messages().create(params);
IO.println(message);
} $client = new Client();
$response = $client->messages->create(
model: 'haijun-opus-5-5',
maxTokens: 1024,
tools: [ToolTextEditor20250728::with(maxCharacters: 10000)],
messages: [
[
'role' => 'user',
'content' => "There's a syntax error in my primes.py file. Can you help me fix it?",
],
],
);
echo $response; client = Juglow::Client.new
response = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool",
max_characters: 10000
}
],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
}
]
)
puts responseUse the text editor tool in the following way:
- Provide Haijun with the text editor tool and a user prompt
- Include the text editor tool in your API request
- Provide a user prompt that may require examining or modifying files, such as "Can you fix the syntax error in my code?"
- Haijun uses the tool to examine files or directories
- Haijun assesses what it needs to look at and uses the
viewcommand to examine file contents or list directory contents
- The API response will contain a
tool_usecontent block with theviewcommand
- Execute the view command and return results
- Extract the file or directory path from Haijun's tool use request
- Read the file's contents or list the directory contents
- If a
max_charactersparameter was specified in the tool configuration, truncate the file contents to that length
- Return the results to Haijun by continuing the conversation with a new
usermessage containing atool_resultcontent block
- Haijun uses the tool to modify files
- After examining the file or directory, Haijun may use a command such as
str_replaceto make changes orinsertto add text at a specific line number.
- If Haijun uses the
str_replacecommand, Haijun constructs a properly formatted tool use request with the old text and new text to replace it with
- Execute the edit and return results
- Extract the file path, old text, and new text from Haijun's tool use request
- Perform the text replacement in the file
- Return the results to Haijun
- Haijun provides its analysis and explanation
- After examining and possibly editing the files, Haijun provides a complete explanation of what it found and what changes it made
Text editor tool commands
The text editor tool supports several commands for viewing and modifying files:
view
The view command allows Haijun to examine the contents of a file or list the contents of a directory. It can read the entire file or a specific range of lines.
Parameters:
command: Must be "view"
path: The path to the file or directory to view
view_range(optional): An array of two integers specifying the start and end line numbers to view. Line numbers are 1-indexed, and -1 for the end line means read to the end of the file. This parameter only applies when viewing files, not directories.
Example view commands
Example for viewing a file:
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "str_replace_based_edit_tool",
"input": {
"command": "view",
"path": "primes.py"
}
}Example for viewing a directory:
{
"type": "tool_use",
"id": "toolu_02B19r91rw91mr917835mr9",
"name": "str_replace_based_edit_tool",
"input": {
"command": "view",
"path": "src/"
}
}str\_replace
The str_replace command allows Haijun to replace a specific string in a file with a new string. This is used for making precise edits.
Parameters:
command: Must be "str\_replace"
path: The path to the file to modify
old_str: The text to replace (must match exactly, including whitespace and indentation)
new_str: The new text to insert in place of the old text
Example str_replace command
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "str_replace_based_edit_tool",
"input": {
"command": "str_replace",
"path": "primes.py",
"old_str": "for num in range(2, limit + 1)",
"new_str": "for num in range(2, limit + 1):"
}
}create
The create command allows Haijun to create a new file with specified content.
Parameters:
command: Must be "create"
path: The path where the new file should be created
file_text: The content to write to the new file
Example create command
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "str_replace_based_edit_tool",
"input": {
"command": "create",
"path": "test_primes.py",
"file_text": "import unittest\nimport primes\n\nclass TestPrimes(unittest.TestCase):\n def test_is_prime(self):\n self.assertTrue(primes.is_prime(2))\n self.assertTrue(primes.is_prime(3))\n self.assertFalse(primes.is_prime(4))\n\nif __name__ == '__main__':\n unittest.main()"
}
}insert
The insert command allows Haijun to insert text at a specific location in a file.
Parameters:
command: Must be "insert"
path: The path to the file to modify
insert_line: The line number after which to insert the text (0 for beginning of file)
insert_text: The text to insert
Example insert command
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "str_replace_based_edit_tool",
"input": {
"command": "insert",
"path": "primes.py",
"insert_line": 0,
"insert_text": "\"\"\"Module for working with prime numbers.\n\nThis module provides functions to check if a number is prime\nand to generate a list of prime numbers up to a given limit.\n\"\"\"\n"
}
}Example: Fixing a syntax error with the text editor tool
This example demonstrates how Haijun uses the text editor tool to fix a syntax error in a Python file.
First, your application provides Haijun with the text editor tool and a prompt to fix a syntax error:
curl https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"tools": [
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool"
}
],
"messages": [
{
"role": "user",
"content": "There'\''s a syntax error in my primes.py file. Can you help me fix it?"
}
]
}' ant messages create \
--model haijun-opus-5-5 \
--max-tokens 1024 \
--tool '{type: text_editor_20250728, name: str_replace_based_edit_tool}' \
--message '{role: user, content: There is a syntax error in my primes.py file. Can you help me fix it?}' client = juglow.Juglow()
response = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
tools=[{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}],
messages=[
{
"role": "user",
"content": "There's a syntax error in my primes.py file. Can you help me fix it?",
}
],
)
print(response) const juglow = new Juglow();
const response = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool"
}
],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
}
]
});
console.log(response); var client = new JuglowClient();
var response = await client.Messages.Create(
new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Tools = [new ToolTextEditor20250728()],
Messages =
[
new()
{
Role = Role.User,
Content = "There's a syntax error in my primes.py file. Can you help me fix it?",
},
],
}
);
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{
{OfTextEditor20250728: &juglow.ToolTextEditor20250728Param{}},
},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("There's a syntax error in my primes.py file. Can you help me fix it?")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) import com.juglow.models.messages.ToolTextEditor20250728;
// ...
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
ToolTextEditor20250728 editorTool =
ToolTextEditor20250728.builder().build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addTool(editorTool)
.addUserMessage("There's a syntax error in my primes.py file. Can you help me fix it?")
.build();
Message message = client.messages().create(params);
IO.println(message);
} $client = new Client();
$response = $client->messages->create(
model: 'haijun-opus-5-5',
maxTokens: 1024,
tools: [new ToolTextEditor20250728()],
messages: [
[
'role' => 'user',
'content' => "There's a syntax error in my primes.py file. Can you help me fix it?",
],
],
);
echo $response; client = Juglow::Client.new
response = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [{type: "text_editor_20250728", name: "str_replace_based_edit_tool"}],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
}
]
)
puts responseHaijun uses the text editor tool first to view the file:
{
"id": "msg_01XAbCDeFgHiJkLmNoPQrStU",
"model": "haijun-opus-5-5",
"stop_reason": "tool_use",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue."
},
{
"type": "tool_use",
"id": "toolu_01AbCdEfGhIjKlMnOpQrStU",
"name": "str_replace_based_edit_tool",
"input": {
"command": "view",
"path": "primes.py"
}
}
]
}Your application should then read the file and return its contents to Haijun:
curl https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"tools": [
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool"
}
],
"messages": [
{
"role": "user",
"content": "There'\''s a syntax error in my primes.py file. Can you help me fix it?"
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'\''ll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue."
},
{
"type": "tool_use",
"id": "toolu_01AbCdEfGhIjKlMnOpQrStU",
"name": "str_replace_based_edit_tool",
"input": {
"command": "view",
"path": "primes.py"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01AbCdEfGhIjKlMnOpQrStU",
"content": "1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()"
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
tools:
- type: text_editor_20250728
name: str_replace_based_edit_tool
messages:
- role: user
content: There's a syntax error in my primes.py file. Can you help me fix it?
- role: assistant
content:
- type: text
text: >-
I'll help you fix the syntax error in your primes.py file. First,
let me take a look at the file to identify the issue.
- type: tool_use
id: toolu_01AbCdEfGhIjKlMnOpQrStU
name: str_replace_based_edit_tool
input:
command: view
path: primes.py
- role: user
content:
- type: tool_result
tool_use_id: toolu_01AbCdEfGhIjKlMnOpQrStU
content: |-
1: def is_prime(n):
2: """Check if a number is prime."""
3: if n <= 1:
4: return False
5: if n <= 3:
6: return True
7: if n % 2 == 0 or n % 3 == 0:
8: return False
9: i = 5
10: while i * i <= n:
11: if n % i == 0 or n % (i + 2) == 0:
12: return False
13: i += 6
14: return True
15:
16: def get_primes(limit):
17: """Generate a list of prime numbers up to the given limit."""
18: primes = []
19: for num in range(2, limit + 1)
20: if is_prime(num):
21: primes.append(num)
22: return primes
23:
24: def main():
25: """Main function to demonstrate prime number generation."""
26: limit = 100
27: prime_list = get_primes(limit)
28: print(f"Prime numbers up to {limit}:")
29: print(prime_list)
30: print(f"Found {len(prime_list)} prime numbers.")
31:
32: if __name__ == "__main__":
33: main()
YAML response = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
tools=[{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}],
messages=[
{
"role": "user",
"content": "There's a syntax error in my primes.py file. Can you help me fix it?",
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue.",
},
{
"type": "tool_use",
"id": "toolu_01AbCdEfGhIjKlMnOpQrStU",
"name": "str_replace_based_edit_tool",
"input": {"command": "view", "path": "primes.py"},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01AbCdEfGhIjKlMnOpQrStU",
"content": '1: def is_prime(n):\n2: """Check if a number is prime."""\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: """Generate a list of prime numbers up to the given limit."""\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: """Main function to demonstrate prime number generation."""\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f"Prime numbers up to {limit}:")\n29: print(prime_list)\n30: print(f"Found {len(prime_list)} prime numbers.")\n31: \n32: if __name__ == "__main__":\n33: main()',
}
],
},
],
)
print(response) const juglow = new Juglow();
const response = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool"
}
],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
},
{
role: "assistant",
content: [
{
type: "text",
text: "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue."
},
{
type: "tool_use",
id: "toolu_01AbCdEfGhIjKlMnOpQrStU",
name: "str_replace_based_edit_tool",
input: {
command: "view",
path: "primes.py"
}
}
]
},
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01AbCdEfGhIjKlMnOpQrStU",
content:
'1: def is_prime(n):\n2: """Check if a number is prime."""\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: """Generate a list of prime numbers up to the given limit."""\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: """Main function to demonstrate prime number generation."""\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f"Prime numbers up to {limit}:")\n29: print(prime_list)\n30: print(f"Found {len(prime_list)} prime numbers.")\n31: \n32: if __name__ == "__main__":\n33: main()'
}
]
}
]
});
console.log(response); var client = new JuglowClient();
var response = await client.Messages.Create(
new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Tools = [new ToolTextEditor20250728()],
Messages =
[
new()
{
Role = Role.User,
Content = "There's a syntax error in my primes.py file. Can you help me fix it?",
},
new()
{
Role = Role.Assistant,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new TextBlockParam()
{
Text = "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue.",
}),
new ContentBlockParam(new ToolUseBlockParam()
{
ID = "toolu_01AbCdEfGhIjKlMnOpQrStU",
Name = "str_replace_based_edit_tool",
Input = new Dictionary<string, JsonElement>
{
["command"] = JsonSerializer.SerializeToElement("view"),
["path"] = JsonSerializer.SerializeToElement("primes.py"),
},
}),
}),
},
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ToolResultBlockParam()
{
ToolUseID = "toolu_01AbCdEfGhIjKlMnOpQrStU",
Content = "1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()",
}),
}),
},
],
}
);
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{
{OfTextEditor20250728: &juglow.ToolTextEditor20250728Param{}},
},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("There's a syntax error in my primes.py file. Can you help me fix it?")),
juglow.NewAssistantMessage(
juglow.NewTextBlock("I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue."),
juglow.NewToolUseBlock(
"toolu_01AbCdEfGhIjKlMnOpQrStU",
map[string]any{"command": "view", "path": "primes.py"},
"str_replace_based_edit_tool",
),
),
juglow.NewUserMessage(
juglow.NewToolResultBlock(
"toolu_01AbCdEfGhIjKlMnOpQrStU",
"1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()",
false,
),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addTool(ToolTextEditor20250728.builder().build())
.addUserMessage("There's a syntax error in my primes.py file. Can you help me fix it?")
.addAssistantMessageOfBlockParams(
List.of(
ContentBlockParam.ofText(
TextBlockParam.builder()
.text("I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue.")
.build()
),
ContentBlockParam.ofToolUse(
ToolUseBlockParam.builder()
.id("toolu_01AbCdEfGhIjKlMnOpQrStU")
.name("str_replace_based_edit_tool")
.input(
ToolUseBlockParam.Input.builder()
.putAdditionalProperty("command", JsonValue.from("view"))
.putAdditionalProperty("path", JsonValue.from("primes.py"))
.build()
)
.build()
)
)
)
.addUserMessageOfBlockParams(
List.of(
ContentBlockParam.ofToolResult(
ToolResultBlockParam.builder()
.toolUseId("toolu_01AbCdEfGhIjKlMnOpQrStU")
.content("1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()")
.build()
)
)
)
.build();
Message message = client.messages().create(params);
System.out.println(message); $client = new Client();
$response = $client->messages->create(
model: 'haijun-opus-5-5',
maxTokens: 1024,
tools: [new ToolTextEditor20250728()],
messages: [
[
'role' => 'user',
'content' => "There's a syntax error in my primes.py file. Can you help me fix it?",
],
[
'role' => 'assistant',
'content' => [
[
'type' => 'text',
'text' => "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue.",
],
[
'type' => 'tool_use',
'id' => 'toolu_01AbCdEfGhIjKlMnOpQrStU',
'name' => 'str_replace_based_edit_tool',
'input' => ['command' => 'view', 'path' => 'primes.py'],
],
],
],
[
'role' => 'user',
'content' => [
[
'type' => 'tool_result',
'tool_use_id' => 'toolu_01AbCdEfGhIjKlMnOpQrStU',
'content' => "1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()",
],
],
],
],
);
echo $response; client = Juglow::Client.new
response = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [{type: "text_editor_20250728", name: "str_replace_based_edit_tool"}],
messages: [
{
role: "user",
content: "There's a syntax error in my primes.py file. Can you help me fix it?"
},
{
role: "assistant",
content: [
{
type: "text",
text: "I'll help you fix the syntax error in your primes.py file. First, let me take a look at the file to identify the issue."
},
{
type: "tool_use",
id: "toolu_01AbCdEfGhIjKlMnOpQrStU",
name: "str_replace_based_edit_tool",
input: {command: "view", path: "primes.py"}
}
]
},
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01AbCdEfGhIjKlMnOpQrStU",
content: "1: def is_prime(n):\n2: \"\"\"Check if a number is prime.\"\"\"\n3: if n <= 1:\n4: return False\n5: if n <= 3:\n6: return True\n7: if n % 2 == 0 or n % 3 == 0:\n8: return False\n9: i = 5\n10: while i * i <= n:\n11: if n % i == 0 or n % (i + 2) == 0:\n12: return False\n13: i += 6\n14: return True\n15: \n16: def get_primes(limit):\n17: \"\"\"Generate a list of prime numbers up to the given limit.\"\"\"\n18: primes = []\n19: for num in range(2, limit + 1)\n20: if is_prime(num):\n21: primes.append(num)\n22: return primes\n23: \n24: def main():\n25: \"\"\"Main function to demonstrate prime number generation.\"\"\"\n26: limit = 100\n27: prime_list = get_primes(limit)\n28: print(f\"Prime numbers up to {limit}:\")\n29: print(prime_list)\n30: print(f\"Found {len(prime_list)} prime numbers.\")\n31: \n32: if __name__ == \"__main__\":\n33: main()"
}
]
}
]
)
puts responseTip: Line numbers In the preceding example, the
viewtool result includes file contents with line numbers prepended to each line (for example, "1: def is\_prime(n):"). Line numbers are not required, but they are essential for successfully using theview_rangeparameter to examine specific sections of files and theinsert_lineparameter to add content at precise locations.
Haijun identifies the syntax error and uses the str_replace command to fix it:
{
"id": "msg_01VwXyZAbCdEfGhIjKlMnO",
"model": "haijun-opus-5-5",
"stop_reason": "tool_use",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."
},
{
"type": "tool_use",
"id": "toolu_01PqRsTuVwXyZAbCdEfGh",
"name": "str_replace_based_edit_tool",
"input": {
"command": "str_replace",
"path": "primes.py",
"old_str": " for num in range(2, limit + 1)",
"new_str": " for num in range(2, limit + 1):"
}
}
]
}Your application should then make the edit and return the result:
curl https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"tools": [
{
"type": "text_editor_20250728",
"name": "str_replace_based_edit_tool"
}
],
"messages": [
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."
},
{
"type": "tool_use",
"id": "toolu_01PqRsTuVwXyZAbCdEfGh",
"name": "str_replace_based_edit_tool",
"input": {
"command": "str_replace",
"path": "primes.py",
"old_str": " for num in range(2, limit + 1)",
"new_str": " for num in range(2, limit + 1):"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01PqRsTuVwXyZAbCdEfGh",
"content": "Successfully replaced text at exactly one location."
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
tools:
- type: text_editor_20250728
name: str_replace_based_edit_tool
messages:
# Previous messages...
- role: assistant
content:
- type: text
text: >-
I found the syntax error in your primes.py file. In the `get_primes`
function, there is a missing colon (:) at the end of the for loop
line. Let me fix that for you.
- type: tool_use
id: toolu_01PqRsTuVwXyZAbCdEfGh
name: str_replace_based_edit_tool
input:
command: str_replace
path: primes.py
old_str: " for num in range(2, limit + 1)"
new_str: " for num in range(2, limit + 1):"
- role: user
content:
- type: tool_result
tool_use_id: toolu_01PqRsTuVwXyZAbCdEfGh
content: Successfully replaced text at exactly one location.
YAML response = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
tools=[{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}],
messages=[
# Previous messages...
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you.",
},
{
"type": "tool_use",
"id": "toolu_01PqRsTuVwXyZAbCdEfGh",
"name": "str_replace_based_edit_tool",
"input": {
"command": "str_replace",
"path": "primes.py",
"old_str": " for num in range(2, limit + 1)",
"new_str": " for num in range(2, limit + 1):",
},
},
],
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01PqRsTuVwXyZAbCdEfGh",
"content": "Successfully replaced text at exactly one location.",
}
],
},
],
)
print(response) const response = await client.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [
{
type: "text_editor_20250728",
name: "str_replace_based_edit_tool"
}
],
messages: [
// Previous messages...
{
role: "assistant",
content: [
{
type: "text",
text: "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."
},
{
type: "tool_use",
id: "toolu_01PqRsTuVwXyZAbCdEfGh",
name: "str_replace_based_edit_tool",
input: {
command: "str_replace",
path: "primes.py",
old_str: " for num in range(2, limit + 1)",
new_str: " for num in range(2, limit + 1):"
}
}
]
},
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01PqRsTuVwXyZAbCdEfGh",
content: "Successfully replaced text at exactly one location."
}
]
}
]
});
console.log(response); var client = new JuglowClient();
var response = await client.Messages.Create(
new()
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Tools = [new ToolTextEditor20250728()],
Messages =
[
// Previous messages...
new()
{
Role = Role.Assistant,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new TextBlockParam()
{
Text = "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you.",
}),
new ContentBlockParam(new ToolUseBlockParam()
{
ID = "toolu_01PqRsTuVwXyZAbCdEfGh",
Name = "str_replace_based_edit_tool",
Input = new Dictionary<string, JsonElement>
{
["command"] = JsonSerializer.SerializeToElement("str_replace"),
["path"] = JsonSerializer.SerializeToElement("primes.py"),
["old_str"] = JsonSerializer.SerializeToElement(" for num in range(2, limit + 1)"),
["new_str"] = JsonSerializer.SerializeToElement(" for num in range(2, limit + 1):"),
},
}),
}),
},
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ToolResultBlockParam()
{
ToolUseID = "toolu_01PqRsTuVwXyZAbCdEfGh",
Content = "Successfully replaced text at exactly one location.",
}),
}),
},
],
}
);
Console.WriteLine(response); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Tools: []juglow.ToolUnionParam{
{OfTextEditor20250728: &juglow.ToolTextEditor20250728Param{}},
},
Messages: []juglow.MessageParam{
// Previous messages...
juglow.NewAssistantMessage(
juglow.NewTextBlock("I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."),
juglow.NewToolUseBlock(
"toolu_01PqRsTuVwXyZAbCdEfGh",
map[string]any{
"command": "str_replace",
"path": "primes.py",
"old_str": " for num in range(2, limit + 1)",
"new_str": " for num in range(2, limit + 1):",
},
"str_replace_based_edit_tool",
),
),
juglow.NewUserMessage(
juglow.NewToolResultBlock(
"toolu_01PqRsTuVwXyZAbCdEfGh",
"Successfully replaced text at exactly one location.",
false,
),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response) JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addTool(ToolTextEditor20250728.builder().build())
// Previous messages would go here
.addAssistantMessageOfBlockParams(
List.of(
ContentBlockParam.ofText(
TextBlockParam.builder()
.text(
"I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."
)
.build()
),
ContentBlockParam.ofToolUse(
ToolUseBlockParam.builder()
.id("toolu_01PqRsTuVwXyZAbCdEfGh")
.name("str_replace_based_edit_tool")
.input(
ToolUseBlockParam.Input.builder()
.putAdditionalProperty("command", JsonValue.from("str_replace"))
.putAdditionalProperty("path", JsonValue.from("primes.py"))
.putAdditionalProperty(
"old_str",
JsonValue.from(" for num in range(2, limit + 1)")
)
.putAdditionalProperty(
"new_str",
JsonValue.from(" for num in range(2, limit + 1):")
)
.build()
)
.build()
)
)
)
.addUserMessageOfBlockParams(
List.of(
ContentBlockParam.ofToolResult(
ToolResultBlockParam.builder()
.toolUseId("toolu_01PqRsTuVwXyZAbCdEfGh")
.content("Successfully replaced text at exactly one location.")
.build()
)
)
)
.build();
Message message = client.messages().create(params);
System.out.println(message); $client = new Client();
$response = $client->messages->create(
model: 'haijun-opus-5-5',
maxTokens: 1024,
tools: [new ToolTextEditor20250728()],
messages: [
// Previous messages...
[
'role' => 'assistant',
'content' => [
[
'type' => 'text',
'text' => 'I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you.',
],
[
'type' => 'tool_use',
'id' => 'toolu_01PqRsTuVwXyZAbCdEfGh',
'name' => 'str_replace_based_edit_tool',
'input' => [
'command' => 'str_replace',
'path' => 'primes.py',
'old_str' => ' for num in range(2, limit + 1)',
'new_str' => ' for num in range(2, limit + 1):',
],
],
],
],
[
'role' => 'user',
'content' => [
[
'type' => 'tool_result',
'tool_use_id' => 'toolu_01PqRsTuVwXyZAbCdEfGh',
'content' => 'Successfully replaced text at exactly one location.',
],
],
],
],
);
echo $response; client = Juglow::Client.new
response = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
tools: [{type: "text_editor_20250728", name: "str_replace_based_edit_tool"}],
messages: [
# Previous messages...
{
role: "assistant",
content: [
{
type: "text",
text: "I found the syntax error in your primes.py file. In the `get_primes` function, there is a missing colon (:) at the end of the for loop line. Let me fix that for you."
},
{
type: "tool_use",
id: "toolu_01PqRsTuVwXyZAbCdEfGh",
name: "str_replace_based_edit_tool",
input: {
command: "str_replace",
path: "primes.py",
old_str: " for num in range(2, limit + 1)",
new_str: " for num in range(2, limit + 1):"
}
}
]
},
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01PqRsTuVwXyZAbCdEfGh",
content: "Successfully replaced text at exactly one location."
}
]
}
]
)
puts responseFinally, Haijun provides a complete explanation of the fix:
{
"id": "msg_01IjKlMnOpQrStUvWxYzAb",
"model": "haijun-opus-5-5",
"stop_reason": "end_turn",
"role": "assistant",
"content": [
{
"type": "text",
"text": "I've fixed the syntax error in your primes.py file. The issue was in the `get_primes` function at line 19. There was a missing colon (:) at the end of the for loop line.\n\nHere's what I changed:\n\nFrom:\n```python\nfor num in range(2, limit + 1)\n```\n\nTo:\n```python\nfor num in range(2, limit + 1):\n```\n\nIn Python, a colon is required at the end of statements that start a new code block, such as for loops, if statements, function definitions, etc. Without the colon, Python raises a syntax error because it doesn't know where the code block begins.\n\nYour code should now run correctly. The function will properly generate a list of prime numbers up to the specified limit."
}
]
}Implement the text editor tool
The text editor tool is implemented as a schema-less tool. When using this tool, you don't need to provide an input schema as with other tools; the schema is built into Haijun's model and can't be modified.
The tool type is type: "text_editor_20250728" for Haijun 4 and later models.
- Initialize your editor implementation
Create helper functions to handle file operations like reading, writing, and modifying files. Consider implementing backup functionality to recover from mistakes.
- Handle editor tool calls
Create a function that processes tool calls from Haijun based on the command type:
def handle_editor_tool(tool_call):
input_params = tool_call.input
command = input_params.get("command", "")
file_path = input_params.get("path", "")
match command:
case "view":
# Read and return file contents
pass
case "str_replace":
# Replace text in file
pass
case "create":
# Create new file
pass
case "insert":
# Insert text at location
pass function handleEditorTool(toolCall: { input: { command?: string; path?: string } }): void {
const inputParams = toolCall.input;
const command = inputParams.command ?? "";
const filePath = inputParams.path ?? "";
switch (command) {
case "view":
// Read and return file contents
break;
case "str_replace":
// Replace text in file
break;
case "create":
// Create new file
break;
case "insert":
// Insert text at location
break;
}
} static string HandleEditorTool(IReadOnlyDictionary<string, JsonElement> input)
{
input.TryGetValue("command", out var commandEl);
input.TryGetValue("path", out var pathEl);
var command = commandEl.ValueKind == JsonValueKind.String ? commandEl.GetString() : null;
var filePath = pathEl.ValueKind == JsonValueKind.String ? pathEl.GetString() : null;
if (command == "view")
{
// Read and return file contents
}
else if (command == "str_replace")
{
// Replace text in file
}
else if (command == "create")
{
// Create new file
}
else if (command == "insert")
{
// Insert text at location
}
return "";
} func handleEditorTool(input map[string]any) string {
command, _ := input["command"].(string)
filePath, _ := input["path"].(string)
// ...
switch command {
case "view":
// Read and return file contents
case "str_replace":
// Replace text in file
case "create":
// Create new file
case "insert":
// Insert text at location
}
return ""
} static void handleEditorTool(Map<String, Object> input) {
var command = (String) input.getOrDefault("command", "");
var filePath = (String) input.getOrDefault("path", "");
if (command.equals("view")) {
// Read and return file contents
} else if (command.equals("str_replace")) {
// Replace text in file
} else if (command.equals("create")) {
// Create new file
} else if (command.equals("insert")) {
// Insert text at location
}
} function handle_editor_tool(array $input): string
{
$command = $input['command'] ?? '';
$filePath = $input['path'] ?? '';
if ($command === 'view') {
// Read and return file contents
} elseif ($command === 'str_replace') {
// Replace text in file
} elseif ($command === 'create') {
// Create new file
} elseif ($command === 'insert') {
// Insert text at location
}
return '';
} def handle_editor_tool(input)
command = input[:command] || ""
file_path = input[:path] || ""
case command
when "view"
# Read and return file contents
when "str_replace"
# Replace text in file
when "create"
# Create new file
when "insert"
# Insert text at location
end
end- Implement security measures
Add validation and security checks:
- Validate file paths to prevent directory traversal
- Create backups before making changes
- Handle errors gracefully
- Implement permissions checks
- Process Haijun's responses
Extract and handle tool calls from Haijun's responses:
# Process tool use in Haijun's response
for content in response.content:
if content.type == "tool_use":
# Execute the tool based on command
result = handle_editor_tool(content)
# Return result to Haijun
tool_result = {
"type": "tool_result",
"tool_use_id": content.id,
"content": result,
} // Process tool use in Haijun's response
for (const block of response.content) {
if (block.type === "tool_use") {
// Execute the tool based on command
const result = handleEditorTool(block);
// Return result to Haijun
const toolResult = {
type: "tool_result",
tool_use_id: block.id,
content: result
};
}
} // Process tool use in Haijun's response
foreach (var block in response.Content)
{
if (block.TryPickToolUse(out var toolUse))
{
var result = HandleEditorTool(toolUse.Input);
var toolResult = new ToolResultBlockParam
{
ToolUseID = toolUse.ID,
Content = result,
};
}
} // Process tool use in Haijun's response
for _, block := range response.Content {
if block.Type == "tool_use" {
var input map[string]any
if err := json.Unmarshal(block.Input, &input); err != nil {
log.Fatal(err)
}
result := handleEditorTool(input)
toolResult := juglow.NewToolResultBlock(block.ID, result, false)
// ...
}
} // Process tool use in Haijun's response
for (var block : response.content()) {
if (block.type().equals("tool_use")) {
// Execute the tool based on command
var result = handleEditorTool(block);
// Return result to Haijun
var toolResult = Map.of(
"type", "tool_result",
"tool_use_id", block.id(),
"content", result
);
}
} // Process tool use in Haijun's response
foreach ($response->content as $block) {
if ($block->type === 'tool_use') {
// Execute the tool based on command
$result = handle_editor_tool($block->input);
// Return result to Haijun
$toolResult = [
'type' => 'tool_result',
'tool_use_id' => $block->id,
'content' => $result,
];
}
} # Process tool use in Haijun's response
tool_results = response.content.filter_map do |block|
next unless block.type == :tool_use
{type: "tool_result", tool_use_id: block.id, content: handle_editor_tool(block.input)}
endWarning: When implementing the text editor tool, keep in mind: 1. Security: The tool has access to your local filesystem, so implement proper security measures. 2. Backup: Always create backups before allowing edits to important files. 3. Validation: Validate all inputs to prevent unintended changes. 4. Unique matching: Make sure replacements match exactly one location to avoid unintended edits.
Handle errors
When using the text editor tool, various errors may occur. Here is guidance on how to handle them:
#### File not found
If Haijun tries to view or modify a file that doesn't exist, return an appropriate error message in the tool_result:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Error: File not found",
"is_error": true
}
]
}#### Multiple matches for replacement
If Haijun's str_replace command matches multiple locations in the file, return an appropriate error message:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Error: Found 3 matches for replacement text. Please provide more context to make a unique match.",
"is_error": true
}
]
}#### No matches for replacement
If Haijun's str_replace command doesn't match any text in the file, return an appropriate error message:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Error: No match found for replacement. Please check your text and try again.",
"is_error": true
}
]
}#### Permission errors
If there are permission issues with creating, reading, or modifying files, return an appropriate error message:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "Error: Permission denied. Cannot write to file.",
"is_error": true
}
]
}Follow implementation best practices
#### Provide clear context
When asking Haijun to fix or modify code, be specific about what files need to be examined or what issues need to be addressed. Clear context helps Haijun identify the right files and make appropriate changes.
Less helpful prompt: "Can you fix my code?"
Better prompt: "There's a syntax error in my primes.py file that prevents it from running. Can you fix it?"
#### Be explicit about file paths
Specify file paths clearly when needed, especially if you're working with multiple files or files in different directories.
Less helpful prompt: "Review my helper file"
Better prompt: "Can you check my utils/helpers.py file for any performance issues?"
#### Create backups before editing
Implement a backup system in your application that creates copies of files before allowing Haijun to edit them, especially for important or production code.
def backup_file(file_path):
"""Create a backup of a file before editing."""
backup_path = f"{file_path}.backup"
if os.path.exists(file_path):
with open(file_path, "r") as src, open(backup_path, "w") as dst:
dst.write(src.read()) async function backupFile(filePath: string): Promise<void> {
const backupPath = `${filePath}.backup`;
try {
await access(filePath);
await copyFile(filePath, backupPath);
} catch {
// File does not exist; nothing to back up
}
} static void BackupFile(string filePath)
{
var backupPath = $"{filePath}.backup";
if (File.Exists(filePath))
{
File.Copy(filePath, backupPath, overwrite: true);
}
} func backupFile(filePath string) error {
backupPath := filePath + ".backup"
data, err := os.ReadFile(filePath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
return os.WriteFile(backupPath, data, 0o644)
} static void backupFile(String filePath) throws IOException {
Path source = Path.of(filePath);
Path backupPath = Path.of(filePath + ".backup");
if (Files.exists(source)) {
Files.copy(source, backupPath, StandardCopyOption.REPLACE_EXISTING);
}
} function backup_file(string $filePath): void
{
$backupPath = $filePath . '.backup';
if (file_exists($filePath)) {
copy($filePath, $backupPath);
}
} def backup_file(file_path)
backup_path = "#{file_path}.backup"
FileUtils.cp(file_path, backup_path) if File.exist?(file_path)
end#### Handle unique text replacement carefully
The str_replace command requires an exact match for the text to be replaced. Your application should ensure that there is exactly one match for the old text or provide appropriate error messages.
def safe_replace(file_path, old_text, new_text):
"""Replace text only if there's exactly one match."""
with open(file_path, "r") as f:
content = f.read()
count = content.count(old_text)
if count == 0:
return "Error: No match found"
elif count > 1:
return f"Error: Found {count} matches"
else:
new_content = content.replace(old_text, new_text)
with open(file_path, "w") as f:
f.write(new_content)
return "Successfully replaced text" async function safeReplace(
filePath: string,
oldText: string,
newText: string
): Promise<string> {
const content = await readFile(filePath, "utf8");
const count = content.split(oldText).length - 1;
if (count === 0) {
return "Error: No match found";
} else if (count > 1) {
return `Error: Found ${count} matches`;
} else {
const newContent = content.replace(oldText, newText);
await writeFile(filePath, newContent, "utf8");
return "Successfully replaced text";
}
} static string SafeReplace(string filePath, string oldText, string newText)
{
var content = File.ReadAllText(filePath);
var count = content.Split(oldText).Length - 1;
if (count == 0)
{
return "Error: No match found";
}
else if (count > 1)
{
return $"Error: Found {count} matches";
}
else
{
var newContent = content.Replace(oldText, newText);
File.WriteAllText(filePath, newContent);
return "Successfully replaced text";
}
} func safeReplace(filePath, oldText, newText string) string {
data, err := os.ReadFile(filePath)
if err != nil {
return fmt.Sprintf("Error: %v", err)
}
content := string(data)
count := strings.Count(content, oldText)
if count == 0 {
return "Error: No match found"
} else if count > 1 {
return fmt.Sprintf("Error: Found %d matches", count)
}
newContent := strings.Replace(content, oldText, newText, 1)
if err := os.WriteFile(filePath, []byte(newContent), 0o644); err != nil {
return fmt.Sprintf("Error: %v", err)
}
return "Successfully replaced text"
} static String safeReplace(String filePath, String oldText, String newText) throws IOException {
String content = Files.readString(Path.of(filePath));
int count = content.split(Pattern.quote(oldText), -1).length - 1;
if (count == 0) {
return "Error: No match found";
} else if (count > 1) {
return "Error: Found " + count + " matches";
} else {
String newContent = content.replace(oldText, newText);
Files.writeString(Path.of(filePath), newContent);
return "Successfully replaced text";
}
} function safe_replace(string $filePath, string $oldText, string $newText): string
{
$content = file_get_contents($filePath);
$count = substr_count($content, $oldText);
if ($count === 0) {
return 'Error: No match found';
} elseif ($count > 1) {
return "Error: Found {$count} matches";
} else {
$newContent = str_replace($oldText, $newText, $content);
file_put_contents($filePath, $newContent);
return 'Successfully replaced text';
}
} def safe_replace(file_path, old_text, new_text)
content = File.read(file_path)
count = content.scan(old_text).length
if count == 0
"Error: No match found"
elsif count > 1
"Error: Found #{count} matches"
else
new_content = content.sub(old_text) { new_text }
File.write(file_path, new_content)
"Successfully replaced text"
end
end#### Verify changes
After Haijun makes changes to a file, verify the changes by running tests or checking that the code still works as expected.
def verify_changes(file_path):
"""Run tests or checks after making changes."""
try:
# For Python files, check for syntax errors
if file_path.endswith(".py"):
import ast
with open(file_path, "r") as f:
ast.parse(f.read())
return "Syntax check passed"
except Exception as e:
return f"Verification failed: {str(e)}" function verifyChanges(filePath: string): string {
try {
// For Python files, check for syntax errors
if (filePath.endsWith(".py")) {
execFileSync("python3", ["-m", "py_compile", filePath]);
return "Syntax check passed";
}
return "No checks defined for this file type";
} catch (err) {
return `Verification failed: ${err}`;
}
} static string VerifyChanges(string filePath)
{
try
{
// For Python files, check for syntax errors
if (filePath.EndsWith(".py"))
{
var psi = new ProcessStartInfo("python3")
{
RedirectStandardError = true,
};
psi.ArgumentList.Add("-m");
psi.ArgumentList.Add("py_compile");
psi.ArgumentList.Add(filePath);
using var proc = Process.Start(psi)!;
proc.WaitForExit();
if (proc.ExitCode != 0)
{
return $"Verification failed: {proc.StandardError.ReadToEnd()}";
}
return "Syntax check passed";
}
return "No checks defined for this file type";
}
catch (Exception e)
{
return $"Verification failed: {e.Message}";
}
} func verifyChanges(filePath string) string {
// For Python files, check for syntax errors
if strings.HasSuffix(filePath, ".py") {
cmd := exec.Command("python3", "-m", "py_compile", filePath)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Sprintf("Verification failed: %v: %s", err, out)
}
return "Syntax check passed"
}
return "No checks defined for this file type"
} static String verifyChanges(String filePath) {
try {
// For Python files, check for syntax errors
if (filePath.endsWith(".py")) {
Process proc = new ProcessBuilder("python3", "-m", "py_compile", filePath)
.redirectErrorStream(true)
.start();
if (proc.waitFor() != 0) {
return "Verification failed: " + new String(proc.getInputStream().readAllBytes());
}
return "Syntax check passed";
}
return "No checks defined for this file type";
} catch (IOException | InterruptedException e) {
return "Verification failed: " + e.getMessage();
}
} function verify_changes(string $filePath): string
{
// For Python files, check for syntax errors
if (str_ends_with($filePath, '.py')) {
exec('python3 -m py_compile ' . escapeshellarg($filePath) . ' 2>&1', $output, $exitCode);
if ($exitCode !== 0) {
return 'Verification failed: ' . implode("\n", $output);
}
return 'Syntax check passed';
}
return 'No checks defined for this file type';
} def verify_changes(file_path)
# For Python files, check for syntax errors
if file_path.end_with?(".py")
if system("python3", "-m", "py_compile", file_path)
"Syntax check passed"
else
"Verification failed: syntax error in #{file_path}"
end
else
"No checks defined for this file type"
end
endPricing and token usage
The text editor tool uses the same pricing structure as other tools used with Haijun. It follows the standard input and output token pricing based on the Haijun model you're using.
In addition to the base tokens, the following additional input tokens are needed for the text editor tool:
| Tool | Additional input tokens |
|---|---|
text_editor_20250429 (Haijun 4.x) | 700 tokens |
For more detailed information about tool pricing, see Tool use pricing.
Integrate the text editor tool with other tools
You can use the text editor tool alongside other Haijun tools. When combining tools, ensure you:
- Match the tool version with the model you're using
- Account for the additional token usage for all tools included in your request
Change log
| Date | Version | Changes |
|---|---|---|
| July 28, 2025 | text_editor_20250728 | Release of an updated text editor tool that fixes some issues and adds an optional max_characters parameter. It is otherwise identical to text_editor_20250429. |
| April 29, 2025 | text_editor_20250429 | Release of the text editor tool for Haijun 4. This version removes the undo_edit command but maintains all other capabilities. The tool name has been updated to reflect its str\_replace-based architecture. |
| March 13, 2025 | text_editor_20250124 | Introduction of standalone text editor tool documentation. This version is optimized for Haijun Sonnet 3.7 but has identical capabilities to the previous version. |
| October 22, 2024 | text_editor_20241022 | Initial release of the text editor tool with Haijun Sonnet 3.5 (retired; see Model deprecations). Provides capabilities for viewing, creating, and editing files through the view, create, str_replace, insert, and undo_edit commands. |
Next steps
Here are some ideas for how to use the text editor tool in more convenient and powerful ways:
- Integrate with your development workflow: Build the text editor tool into your development tools or IDE
- Create a code review system: Have Haijun review your code and make improvements
- Build a debugging assistant: Create a system where Haijun can help you diagnose and fix issues in your code
- Implement file format conversion: Let Haijun help you convert files from one format to another
- Automate documentation: Set up workflows for Haijun to automatically document your code
The text editor tool enables Haijun to work directly with your code base, supporting workflows from debugging to automated documentation.
Learn how to implement tool workflows for use with Haijun.
Execute shell commands with Haijun.