attachment.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package attachment
  2. import (
  3. "github.com/google/uuid"
  4. )
  5. type TextSource struct {
  6. Value string `toml:"value"`
  7. }
  8. type FileSource struct {
  9. Path string `toml:"path"`
  10. Mime string `toml:"mime"`
  11. Data []byte `toml:"data,omitempty"` // Optional for image data
  12. }
  13. type SymbolSource struct {
  14. Path string `toml:"path"`
  15. Name string `toml:"name"`
  16. Kind int `toml:"kind"`
  17. Range SymbolRange `toml:"range"`
  18. }
  19. type SymbolRange struct {
  20. Start Position `toml:"start"`
  21. End Position `toml:"end"`
  22. }
  23. type AgentSource struct {
  24. Name string `toml:"name"`
  25. }
  26. type Position struct {
  27. Line int `toml:"line"`
  28. Char int `toml:"char"`
  29. }
  30. type Attachment struct {
  31. ID string `toml:"id"`
  32. Type string `toml:"type"`
  33. Display string `toml:"display"`
  34. URL string `toml:"url"`
  35. Filename string `toml:"filename"`
  36. MediaType string `toml:"media_type"`
  37. StartIndex int `toml:"start_index"`
  38. EndIndex int `toml:"end_index"`
  39. Source any `toml:"source,omitempty"`
  40. }
  41. // NewAttachment creates a new attachment with a unique ID
  42. func NewAttachment() *Attachment {
  43. return &Attachment{
  44. ID: uuid.NewString(),
  45. }
  46. }
  47. func (a *Attachment) GetTextSource() (*TextSource, bool) {
  48. if a.Type != "text" {
  49. return nil, false
  50. }
  51. ts, ok := a.Source.(*TextSource)
  52. return ts, ok
  53. }
  54. // GetFileSource returns the source as FileSource if the attachment is a file type
  55. func (a *Attachment) GetFileSource() (*FileSource, bool) {
  56. if a.Type != "file" {
  57. return nil, false
  58. }
  59. fs, ok := a.Source.(*FileSource)
  60. return fs, ok
  61. }
  62. // GetSymbolSource returns the source as SymbolSource if the attachment is a symbol type
  63. func (a *Attachment) GetSymbolSource() (*SymbolSource, bool) {
  64. if a.Type != "symbol" {
  65. return nil, false
  66. }
  67. ss, ok := a.Source.(*SymbolSource)
  68. return ss, ok
  69. }
  70. // GetAgentSource returns the source as AgentSource if the attachment is an agent type
  71. func (a *Attachment) GetAgentSource() (*AgentSource, bool) {
  72. if a.Type != "agent" {
  73. return nil, false
  74. }
  75. as, ok := a.Source.(*AgentSource)
  76. return as, ok
  77. }
  78. // FromMap creates a TextSource from a map[string]any
  79. func (ts *TextSource) FromMap(sourceMap map[string]any) {
  80. if value, ok := sourceMap["value"].(string); ok {
  81. ts.Value = value
  82. }
  83. }
  84. // FromMap creates a FileSource from a map[string]any
  85. func (fs *FileSource) FromMap(sourceMap map[string]any) {
  86. if path, ok := sourceMap["path"].(string); ok {
  87. fs.Path = path
  88. }
  89. if mime, ok := sourceMap["mime"].(string); ok {
  90. fs.Mime = mime
  91. }
  92. if data, ok := sourceMap["data"].([]byte); ok {
  93. fs.Data = data
  94. }
  95. }
  96. // FromMap creates a SymbolSource from a map[string]any
  97. func (ss *SymbolSource) FromMap(sourceMap map[string]any) {
  98. if path, ok := sourceMap["path"].(string); ok {
  99. ss.Path = path
  100. }
  101. if name, ok := sourceMap["name"].(string); ok {
  102. ss.Name = name
  103. }
  104. if kind, ok := sourceMap["kind"].(int); ok {
  105. ss.Kind = kind
  106. }
  107. if rangeMap, ok := sourceMap["range"].(map[string]any); ok {
  108. ss.Range = SymbolRange{}
  109. if startMap, ok := rangeMap["start"].(map[string]any); ok {
  110. if line, ok := startMap["line"].(int); ok {
  111. ss.Range.Start.Line = line
  112. }
  113. if char, ok := startMap["char"].(int); ok {
  114. ss.Range.Start.Char = char
  115. }
  116. }
  117. if endMap, ok := rangeMap["end"].(map[string]any); ok {
  118. if line, ok := endMap["line"].(int); ok {
  119. ss.Range.End.Line = line
  120. }
  121. if char, ok := endMap["char"].(int); ok {
  122. ss.Range.End.Char = char
  123. }
  124. }
  125. }
  126. }
  127. // FromMap creates an AgentSource from a map[string]any
  128. func (as *AgentSource) FromMap(sourceMap map[string]any) {
  129. if name, ok := sourceMap["name"].(string); ok {
  130. as.Name = name
  131. }
  132. }
  133. // RestoreSourceType converts a map[string]any source back to the proper type
  134. func (a *Attachment) RestoreSourceType() {
  135. if a.Source == nil {
  136. return
  137. }
  138. // Check if Source is a map[string]any
  139. if sourceMap, ok := a.Source.(map[string]any); ok {
  140. switch a.Type {
  141. case "text":
  142. ts := &TextSource{}
  143. ts.FromMap(sourceMap)
  144. a.Source = ts
  145. case "file":
  146. fs := &FileSource{}
  147. fs.FromMap(sourceMap)
  148. a.Source = fs
  149. case "symbol":
  150. ss := &SymbolSource{}
  151. ss.FromMap(sourceMap)
  152. a.Source = ss
  153. case "agent":
  154. as := &AgentSource{}
  155. as.FromMap(sourceMap)
  156. a.Source = as
  157. }
  158. }
  159. }