context.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package chatbot
  2. import (
  3. "github.com/0xJacky/Nginx-UI/internal/helper"
  4. "github.com/0xJacky/Nginx-UI/internal/logger"
  5. "github.com/0xJacky/Nginx-UI/internal/nginx"
  6. "github.com/sashabaranov/go-openai"
  7. "os"
  8. "regexp"
  9. "strings"
  10. )
  11. type includeContext struct {
  12. Paths []string
  13. PathsMap map[string]bool
  14. }
  15. func IncludeContext(filename string) (includes []string) {
  16. c := &includeContext{
  17. Paths: make([]string, 0),
  18. PathsMap: make(map[string]bool),
  19. }
  20. c.extractIncludes(filename)
  21. return c.Paths
  22. }
  23. // extractIncludes extracts all include statements from the given nginx configuration file.
  24. func (c *includeContext) extractIncludes(filename string) {
  25. if !helper.FileExists(filename) {
  26. logger.Error("File does not exist: ", filename)
  27. return
  28. }
  29. // Read the file content
  30. content, err := os.ReadFile(filename)
  31. if err != nil {
  32. logger.Error(err)
  33. return
  34. }
  35. // Find all include statements
  36. pattern := regexp.MustCompile(`(?m)^\s*include\s+([^;]+);`)
  37. matches := pattern.FindAllStringSubmatch(string(content), -1)
  38. for _, match := range matches {
  39. if len(match) > 1 {
  40. // Resolve the path of the included file
  41. includePath := match[1]
  42. // to avoid infinite loop
  43. if c.PathsMap[includePath] {
  44. continue
  45. }
  46. c.push(includePath)
  47. // Recursively extract includes from the included file
  48. c.extractIncludes(includePath)
  49. }
  50. }
  51. return
  52. }
  53. func (c *includeContext) push(path string) {
  54. c.Paths = append(c.Paths, path)
  55. c.PathsMap[path] = true
  56. }
  57. // getConfigIncludeContext returns the context of the given filename.
  58. func getConfigIncludeContext(filename string) (multiContent []openai.ChatMessagePart) {
  59. multiContent = make([]openai.ChatMessagePart, 0)
  60. if !helper.IsUnderDirectory(filename, nginx.GetConfPath()) {
  61. return
  62. }
  63. includes := IncludeContext(filename)
  64. logger.Debug(includes)
  65. var sb strings.Builder
  66. for _, include := range includes {
  67. text, _ := os.ReadFile(nginx.GetConfPath(include))
  68. if len(text) == 0 {
  69. continue
  70. }
  71. sb.WriteString("The Content of ")
  72. sb.WriteString(include)
  73. sb.WriteString(",")
  74. sb.WriteString(string(text))
  75. multiContent = append(multiContent, openai.ChatMessagePart{
  76. Type: openai.ChatMessagePartTypeText,
  77. Text: sb.String(),
  78. })
  79. sb.Reset()
  80. }
  81. return
  82. }