@@ -101,118 +101,144 @@ func (t *socialNearbyTool) Call(ctx context.Context, argsJSON string) string {
101101 return sb .String ()
102102}
103103
104- // ── social_mail_send ──────────────────────────────────────────────────────────
104+ // ── social_dm_send ── ──────────────────────────────────────────────────────────
105105
106- type socialMailSendTool struct { client * market.Client }
106+ type socialDmSendTool struct { client * market.Client }
107107
108- func NewSocialMailSendTool (mc * market.Client ) Tool { return & socialMailSendTool {client : mc } }
108+ func NewSocialDmSendTool (mc * market.Client ) Tool { return & socialDmSendTool {client : mc } }
109109
110- func (t * socialMailSendTool ) Def () ToolDef {
110+ func (t * socialDmSendTool ) Def () ToolDef {
111111 return ToolDef {
112- Name : "social_mail_send " ,
113- Description : "Send a letter to a friend agent. You must follow the recipient first ." ,
112+ Name : "social_dm_send " ,
113+ Description : "Send a direct message to another agent. Automatically creates or reuses the DM thread ." ,
114114 Parameters : ToolParameters {
115115 Type : "object" ,
116116 Properties : map [string ]ToolProperty {
117117 "recipient_id" : {
118118 Type : "string" ,
119119 Description : "The agent ID of the recipient." ,
120120 },
121- "subject " : {
121+ "body " : {
122122 Type : "string" ,
123- Description : "Subject line (max 100 chars)." ,
124- },
125- "content" : {
126- Type : "string" ,
127- Description : "Letter body (max 2000 chars)." ,
123+ Description : "Message content (max 4000 chars)." ,
128124 },
129125 },
130- Required : []string {"recipient_id" , "subject" , "content " },
126+ Required : []string {"recipient_id" , "body " },
131127 },
132128 }
133129}
134130
135- func (t * socialMailSendTool ) Call (ctx context.Context , argsJSON string ) string {
131+ func (t * socialDmSendTool ) Call (ctx context.Context , argsJSON string ) string {
136132 var args struct {
137133 RecipientID string `json:"recipient_id"`
138- Subject string `json:"subject"`
139- Content string `json:"content"`
134+ Body string `json:"body"`
140135 }
141136 if err := json .Unmarshal ([]byte (argsJSON ), & args ); err != nil {
142137 return "error: invalid arguments: " + err .Error ()
143138 }
144139 if strings .TrimSpace (args .RecipientID ) == "" {
145140 return "error: recipient_id is required"
146141 }
147- if strings .TrimSpace (args .Subject ) == "" {
148- return "error: subject is required"
142+ if strings .TrimSpace (args .Body ) == "" {
143+ return "error: body is required"
149144 }
150- if strings .TrimSpace (args .Content ) == "" {
151- return "error: content is required"
145+ threadID , err := t .client .GetOrCreateDm (ctx , args .RecipientID )
146+ if err != nil {
147+ return fmt .Sprintf ("error creating DM thread with %s: %s" , args .RecipientID , err )
152148 }
153- if err := t .client .SendMail (ctx , args . RecipientID , args .Subject , args . Content ); err != nil {
154- return fmt .Sprintf ("error sending mail to %s : %s" , args . RecipientID , err )
149+ if err := t .client .SendThreadMessage (ctx , threadID , args .Body ); err != nil {
150+ return fmt .Sprintf ("error sending message : %s" , err )
155151 }
156- return fmt .Sprintf ("Letter sent to %s." , args .RecipientID )
152+ return fmt .Sprintf ("Message sent to %s." , args .RecipientID )
157153}
158154
159- // ── social_mail_read ──── ──────────────────────────────────────────────────────
155+ // ── social_messages_list ──────────────────────────────────────────────────────
160156
161- type socialMailReadTool struct { client * market.Client }
157+ type socialMessagesListTool struct { client * market.Client }
162158
163- func NewSocialMailReadTool (mc * market.Client ) Tool { return & socialMailReadTool {client : mc } }
159+ func NewSocialMessagesListTool (mc * market.Client ) Tool { return & socialMessagesListTool {client : mc } }
164160
165- func (t * socialMailReadTool ) Def () ToolDef {
161+ func (t * socialMessagesListTool ) Def () ToolDef {
166162 return ToolDef {
167- Name : "social_mail_read" ,
168- Description : "Read your mail. Use box=inbox to see received letters, box=outbox for sent. Pass letter_id to read a specific letter." ,
163+ Name : "social_messages_list" ,
164+ Description : "List your message threads (DMs and group chats). Shows the most recent message and unread count for each." ,
165+ Parameters : ToolParameters {Type : "object" , Properties : map [string ]ToolProperty {}},
166+ }
167+ }
168+
169+ func (t * socialMessagesListTool ) Call (ctx context.Context , _ string ) string {
170+ threads , err := t .client .ListThreads (ctx )
171+ if err != nil {
172+ return fmt .Sprintf ("error listing threads: %s" , err )
173+ }
174+ if len (threads ) == 0 {
175+ return "No message threads yet."
176+ }
177+ var sb strings.Builder
178+ sb .WriteString (fmt .Sprintf ("=== Messages (%d threads) ===\n " , len (threads )))
179+ for _ , th := range threads {
180+ unread := ""
181+ if th .UnreadCount > 0 {
182+ unread = fmt .Sprintf (" [%d unread]" , th .UnreadCount )
183+ }
184+ name := th .Title
185+ if name == "" && th .OtherAgentID != "" {
186+ name = th .OtherAgentID
187+ }
188+ preview := th .LastMessage
189+ if len (preview ) > 80 {
190+ preview = preview [:80 ] + "…"
191+ }
192+ sb .WriteString (fmt .Sprintf ("- [%s] %s%s\n %s\n " , th .ThreadID [:8 ], name , unread , preview ))
193+ }
194+ return strings .TrimRight (sb .String (), "\n " )
195+ }
196+
197+ // ── social_messages_read ──────────────────────────────────────────────────────
198+
199+ type socialMessagesReadTool struct { client * market.Client }
200+
201+ func NewSocialMessagesReadTool (mc * market.Client ) Tool { return & socialMessagesReadTool {client : mc } }
202+
203+ func (t * socialMessagesReadTool ) Def () ToolDef {
204+ return ToolDef {
205+ Name : "social_messages_read" ,
206+ Description : "Read messages in a thread. Use social_messages_list first to get thread IDs." ,
169207 Parameters : ToolParameters {
170208 Type : "object" ,
171209 Properties : map [string ]ToolProperty {
172- "box" : {
173- Type : "string" ,
174- Description : "Which mailbox to read: 'inbox' or 'outbox'. Ignored when letter_id is set." ,
175- },
176- "letter_id" : {
210+ "thread_id" : {
177211 Type : "string" ,
178- Description : "ID of a specific letter to read (marks it as read) ." ,
212+ Description : "Thread UUID from social_messages_list ." ,
179213 },
180214 },
215+ Required : []string {"thread_id" },
181216 },
182217 }
183218}
184219
185- func (t * socialMailReadTool ) Call (ctx context.Context , argsJSON string ) string {
220+ func (t * socialMessagesReadTool ) Call (ctx context.Context , argsJSON string ) string {
186221 var args struct {
187- Box string `json:"box"`
188- LetterID string `json:"letter_id"`
222+ ThreadID string `json:"thread_id"`
189223 }
190224 if err := json .Unmarshal ([]byte (argsJSON ), & args ); err != nil {
191225 return "error: invalid arguments: " + err .Error ()
192226 }
193- box := args .Box
194- if box == "" && args .LetterID == "" {
195- box = "inbox"
227+ if strings .TrimSpace (args .ThreadID ) == "" {
228+ return "error: thread_id is required"
196229 }
197- letters , err := t .client .ReadMail (ctx , box , args .LetterID )
230+ msgs , err := t .client .GetThreadMessages (ctx , args .ThreadID )
198231 if err != nil {
199- return fmt .Sprintf ("error reading mail : %s" , err )
232+ return fmt .Sprintf ("error reading messages : %s" , err )
200233 }
201- if len (letters ) == 0 {
202- return "No letters found ."
234+ if len (msgs ) == 0 {
235+ return "No messages in this thread ."
203236 }
237+ // Mark as read (fire-and-forget)
238+ go func () { _ = t .client .MarkThreadRead (ctx , args .ThreadID ) }()
204239 var sb strings.Builder
205- for _ , l := range letters {
206- readMark := ""
207- if ! l .Read {
208- readMark = " [UNREAD]"
209- }
210- sb .WriteString (fmt .Sprintf ("--- From: %s | ID: %s%s ---\n " , l .SenderID , l .ID , readMark ))
211- sb .WriteString (fmt .Sprintf ("Subject: %s\n " , l .Subject ))
212- if l .Content != "" {
213- sb .WriteString (fmt .Sprintf ("%s\n " , l .Content ))
214- }
215- sb .WriteString ("\n " )
240+ for _ , m := range msgs {
241+ sb .WriteString (fmt .Sprintf ("[%s | %s]\n %s\n \n " , m .FromAgentID , m .CreatedAt [:16 ], m .Body ))
216242 }
217243 return strings .TrimRight (sb .String (), "\n " )
218244}
0 commit comments