ant: improve encapsulation
- Replace string literals with package constants for message roles and content types.
- Create UserStringMessage helper function to simplify user message creation
- Replace manual Content creation with ant.StringContent()
Co-Authored-By: sketch <hello@sketch.dev>
diff --git a/loop/agent.go b/loop/agent.go
index adbdf51..315ff89 100644
--- a/loop/agent.go
+++ b/loop/agent.go
@@ -613,7 +613,7 @@
if resp.StopReason == ant.StopReasonToolUse {
var toolCalls []ToolCall
for _, part := range resp.Content {
- if part.Type == "tool_use" {
+ if part.Type == ant.ContentTypeToolUse {
toolCalls = append(toolCalls, ToolCall{
Name: part.ToolName,
Input: string(part.ToolInput),
@@ -997,13 +997,13 @@
case <-ctx.Done():
return m, ctx.Err()
case msg := <-a.inbox:
- m = append(m, ant.Content{Type: "text", Text: msg})
+ m = append(m, ant.StringContent(msg))
}
}
for {
select {
case msg := <-a.inbox:
- m = append(m, ant.Content{Type: "text", Text: msg})
+ m = append(m, ant.StringContent(msg))
default:
return m, nil
}
@@ -1087,7 +1087,7 @@
}
userMessage := ant.Message{
- Role: "user",
+ Role: ant.MessageRoleUser,
Content: msgs,
}
@@ -1211,19 +1211,19 @@
// Inject any auto-generated messages from quality checks
for _, msg := range autoqualityMessages {
- msgs = append(msgs, ant.Content{Type: "text", Text: msg})
+ msgs = append(msgs, ant.StringContent(msg))
}
// Handle cancellation by appending a message about it
if cancelled {
- msgs = append(msgs, ant.Content{Type: "text", Text: cancelToolUseMessage})
+ msgs = append(msgs, ant.StringContent(cancelToolUseMessage))
// EndOfTurn is false here so that the client of this agent keeps processing
// further messages; the conversation is not over.
a.pushToOutbox(ctx, AgentMessage{Type: ErrorMessageType, Content: userCancelMessage, EndOfTurn: false})
} else if err := a.convo.OverBudget(); err != nil {
// Handle budget issues by appending a message about it
budgetMsg := "We've exceeded our budget. Please ask the user to confirm before continuing by ending the turn."
- msgs = append(msgs, ant.Content{Type: "text", Text: budgetMsg})
+ msgs = append(msgs, ant.StringContent(budgetMsg))
a.pushToOutbox(ctx, budgetMessage(fmt.Errorf("warning: %w (ask to keep trying, if you'd like)", err)))
}
@@ -1233,7 +1233,7 @@
// Send the combined message to continue the conversation
a.stateMachine.Transition(ctx, StateSendingToolResults, "Sending tool results back to LLM")
resp, err := a.convo.SendMessage(ant.Message{
- Role: "user",
+ Role: ant.MessageRoleUser,
Content: results,
})
if err != nil {
@@ -1268,7 +1268,7 @@
// Collect all text content
var allText strings.Builder
for _, content := range msg.Content {
- if content.Type == "text" && content.Text != "" {
+ if content.Type == ant.ContentTypeText && content.Text != "" {
if allText.Len() > 0 {
allText.WriteString("\n\n")
}
@@ -1604,10 +1604,7 @@
Reply with ONLY the reprompt text.
`
- userMessage := ant.Message{
- Role: "user",
- Content: []ant.Content{{Type: "text", Text: msg}},
- }
+ userMessage := ant.UserStringMessage(msg)
// By doing this in a subconversation, the agent doesn't call tools (because
// there aren't any), and there's not a concurrency risk with on-going other
// outstanding conversations.