context.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package llm
  2. import (
  3. "github.com/0xJacky/Nginx-UI/internal/helper"
  4. "github.com/0xJacky/Nginx-UI/internal/nginx"
  5. "github.com/sashabaranov/go-openai"
  6. "github.com/uozi-tech/cosy/logger"
  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. if !helper.IsUnderDirectory(filename, nginx.GetConfPath()) {
  30. logger.Error("File is not under the nginx conf path: ", filename)
  31. return
  32. }
  33. // Read the file content
  34. content, err := os.ReadFile(filename)
  35. if err != nil {
  36. logger.Error(err)
  37. return
  38. }
  39. // Find all include statements
  40. pattern := regexp.MustCompile(`(?m)^\s*include\s+([^;]+);`)
  41. matches := pattern.FindAllStringSubmatch(string(content), -1)
  42. for _, match := range matches {
  43. if len(match) > 1 {
  44. // Resolve the path of the included file
  45. includePath := match[1]
  46. // to avoid infinite loop
  47. if c.PathsMap[includePath] {
  48. continue
  49. }
  50. c.push(includePath)
  51. // Recursively extract includes from the included file
  52. c.extractIncludes(includePath)
  53. }
  54. }
  55. return
  56. }
  57. func (c *includeContext) push(path string) {
  58. c.Paths = append(c.Paths, path)
  59. c.PathsMap[path] = true
  60. }
  61. // getConfigIncludeContext returns the context of the given filename.
  62. func getConfigIncludeContext(filename string) (multiContent []openai.ChatMessagePart) {
  63. multiContent = make([]openai.ChatMessagePart, 0)
  64. if !helper.IsUnderDirectory(filename, nginx.GetConfPath()) {
  65. return
  66. }
  67. includes := IncludeContext(filename)
  68. logger.Debug(includes)
  69. var sb strings.Builder
  70. for _, include := range includes {
  71. text, _ := os.ReadFile(nginx.GetConfPath(include))
  72. if len(text) == 0 {
  73. continue
  74. }
  75. sb.WriteString("The Content of ")
  76. sb.WriteString(include)
  77. sb.WriteString(",")
  78. sb.WriteString(string(text))
  79. multiContent = append(multiContent, openai.ChatMessagePart{
  80. Type: openai.ChatMessagePartTypeText,
  81. Text: sb.String(),
  82. })
  83. sb.Reset()
  84. }
  85. return
  86. }