MCPcopy Create free account
hub / github.com/coder/coder / injectMissingToolUses

Function injectMissingToolUses

coderd/x/chatd/chatprompt/chatprompt.go:1036–1132  ·  view source on GitHub ↗
(
	prompt []fantasy.Message,
	toolNameByCallID map[string]string,
)

Source from the content-addressed store, hash-verified

1034}
1035
1036func injectMissingToolUses(
1037 prompt []fantasy.Message,
1038 toolNameByCallID map[string]string,
1039) []fantasy.Message {
1040 result := make([]fantasy.Message, 0, len(prompt))
1041 for _, msg := range prompt {
1042 if msg.Role != fantasy.MessageRoleTool {
1043 result = append(result, msg)
1044 continue
1045 }
1046
1047 allToolResults := make([]fantasy.ToolResultPart, 0, len(msg.Content))
1048 for _, part := range msg.Content {
1049 toolResult, ok := safeAsToolResultPart(part)
1050 if !ok {
1051 continue
1052 }
1053 allToolResults = append(allToolResults, toolResult)
1054 }
1055 if len(allToolResults) == 0 {
1056 result = append(result, msg)
1057 continue
1058 }
1059
1060 // Provider-executed tool results may be persisted in a
1061 // later step than the assistant message that initiated the
1062 // tool call. When that happens they appear as orphans after
1063 // the wrong assistant message. Filter them out before
1064 // matching because they cannot be converted into local
1065 // tool-use pairs safely.
1066 toolResults := make([]fantasy.ToolResultPart, 0, len(allToolResults))
1067 for _, tr := range allToolResults {
1068 if !tr.ProviderExecuted {
1069 toolResults = append(toolResults, tr)
1070 }
1071 }
1072 if len(toolResults) == 0 {
1073 // All results were provider-executed; drop the message.
1074 continue
1075 }
1076
1077 // Walk backwards through the result to find the nearest
1078 // preceding assistant message (skipping over other tool
1079 // messages that belong to the same batch of results).
1080 answeredByPrevious := make(map[string]struct{})
1081 for k := len(result) - 1; k >= 0; k-- {
1082 if result[k].Role == fantasy.MessageRoleAssistant {
1083 for _, toolCall := range ExtractToolCalls(result[k].Content) {
1084 toolCallID := sanitizeToolCallID(toolCall.ToolCallID)
1085 if toolCallID == "" {
1086 continue
1087 }
1088 answeredByPrevious[toolCallID] = struct{}{}
1089 }
1090 break
1091 }
1092 if result[k].Role != fantasy.MessageRoleTool {
1093 break

Callers 1

ConvertMessagesWithFilesFunction · 0.85

Calls 5

safeAsToolResultPartFunction · 0.85
ExtractToolCallsFunction · 0.85
sanitizeToolCallIDFunction · 0.85
syntheticToolUseMessageFunction · 0.85

Tested by

no test coverage detected