mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(tool-feedback): format tool args as JSON code blocks
This commit is contained in:
@@ -7,21 +7,31 @@ import (
|
||||
|
||||
const ToolFeedbackContinuationHint = "Continuing the current task."
|
||||
|
||||
// FormatToolFeedbackMessage renders the model-provided explanation for why a
|
||||
// tool is being executed. When the model does not provide one, it keeps only
|
||||
// the tool line and does not expose raw arguments or fallback text.
|
||||
func FormatToolFeedbackMessage(toolName, explanation string) string {
|
||||
// FormatToolFeedbackMessage renders a tool feedback message for chat channels.
|
||||
// It keeps the tool name on the first line for animation and can include both
|
||||
// a human explanation and the serialized tool arguments in the body.
|
||||
func FormatToolFeedbackMessage(toolName, explanation, argsPreview string) string {
|
||||
toolName = strings.TrimSpace(toolName)
|
||||
explanation = strings.TrimSpace(explanation)
|
||||
argsPreview = strings.TrimSpace(argsPreview)
|
||||
|
||||
bodyLines := make([]string, 0, 2)
|
||||
if explanation != "" {
|
||||
bodyLines = append(bodyLines, explanation)
|
||||
}
|
||||
if argsPreview != "" {
|
||||
bodyLines = append(bodyLines, "```json\n"+argsPreview+"\n```")
|
||||
}
|
||||
body := strings.Join(bodyLines, "\n")
|
||||
|
||||
if toolName == "" {
|
||||
return explanation
|
||||
return body
|
||||
}
|
||||
if explanation == "" {
|
||||
if body == "" {
|
||||
return fmt.Sprintf("\U0001f527 `%s`", toolName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("\U0001f527 `%s`\n%s", toolName, explanation)
|
||||
return fmt.Sprintf("\U0001f527 `%s`\n%s", toolName, body)
|
||||
}
|
||||
|
||||
// FitToolFeedbackMessage keeps tool feedback within a single outbound message.
|
||||
|
||||
@@ -6,29 +6,38 @@ func TestFormatToolFeedbackMessage(t *testing.T) {
|
||||
got := FormatToolFeedbackMessage(
|
||||
"read_file",
|
||||
"I will read README.md first to confirm the current project structure.",
|
||||
"{\n \"path\": \"README.md\"\n}",
|
||||
)
|
||||
want := "\U0001f527 `read_file`\nI will read README.md first to confirm the current project structure."
|
||||
want := "\U0001f527 `read_file`\nI will read README.md first to confirm the current project structure.\n```json\n{\n \"path\": \"README.md\"\n}\n```"
|
||||
if got != want {
|
||||
t.Fatalf("FormatToolFeedbackMessage() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatToolFeedbackMessage_EmptyExplanationKeepsOnlyToolLine(t *testing.T) {
|
||||
got := FormatToolFeedbackMessage("read_file", "")
|
||||
want := "\U0001f527 `read_file`"
|
||||
func TestFormatToolFeedbackMessage_EmptyExplanationShowsArgs(t *testing.T) {
|
||||
got := FormatToolFeedbackMessage("read_file", "", "{\n \"path\": \"README.md\"\n}")
|
||||
want := "\U0001f527 `read_file`\n```json\n{\n \"path\": \"README.md\"\n}\n```"
|
||||
if got != want {
|
||||
t.Fatalf("FormatToolFeedbackMessage() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatToolFeedbackMessage_EmptyToolNameOmitsToolLine(t *testing.T) {
|
||||
got := FormatToolFeedbackMessage("", "Continue drafting the final response.")
|
||||
got := FormatToolFeedbackMessage("", "Continue drafting the final response.", "")
|
||||
want := "Continue drafting the final response."
|
||||
if got != want {
|
||||
t.Fatalf("FormatToolFeedbackMessage() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatToolFeedbackMessage_EmptyExplanationAndArgsKeepsOnlyToolLine(t *testing.T) {
|
||||
got := FormatToolFeedbackMessage("read_file", "", "")
|
||||
want := "\U0001f527 `read_file`"
|
||||
if got != want {
|
||||
t.Fatalf("FormatToolFeedbackMessage() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFitToolFeedbackMessage_TruncatesBodyWithinSingleMessage(t *testing.T) {
|
||||
got := FitToolFeedbackMessage(
|
||||
"\U0001f527 `read_file`\nRead README.md first to confirm the current project structure.",
|
||||
|
||||
Reference in New Issue
Block a user