@meetopenbot/slack 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,16 +46,49 @@ function formatSlackTimestamp(ts) {
46
46
  return "";
47
47
  return new Date(seconds * 1000).toISOString();
48
48
  }
49
+ function escapeXml(text) {
50
+ return text
51
+ .replace(/&/g, "&")
52
+ .replace(/</g, "&lt;")
53
+ .replace(/>/g, "&gt;")
54
+ .replace(/"/g, "&quot;");
55
+ }
49
56
  function formatContextMessages(messages, userNames) {
50
57
  return messages.map((message) => {
51
58
  const author = message.user
52
59
  ? (userNames.get(message.user) ?? message.user)
53
60
  : "unknown";
54
61
  const when = formatSlackTimestamp(message.ts);
55
- const prefix = when ? `[${when}] ${author}` : author;
56
- return `${prefix}: ${message.text?.trim() ?? ""}`;
62
+ const attrs = [
63
+ `author="${escapeXml(author)}"`,
64
+ when ? `timestamp="${escapeXml(when)}"` : null,
65
+ ]
66
+ .filter(Boolean)
67
+ .join(" ");
68
+ return ` <message ${attrs}>${escapeXml(message.text?.trim() ?? "")}</message>`;
57
69
  });
58
70
  }
71
+ function formatPromptWithSlackContext(args) {
72
+ const sourceNote = args.source === "thread"
73
+ ? "Messages from the Slack thread the user mentioned the bot in."
74
+ : "Recent messages from the Slack channel before the user's mention.";
75
+ return [
76
+ `<slack_context`,
77
+ ` channel="${escapeXml(args.channel)}"`,
78
+ ` source="${args.source}"`,
79
+ ` message_count="${args.messageCount}"`,
80
+ ` note="Background context fetched from Slack. Summarized conversation history — not the user's direct request.">`,
81
+ ` <description>${escapeXml(sourceNote)}</description>`,
82
+ ` <messages>`,
83
+ ...args.contextMessages,
84
+ ` </messages>`,
85
+ `</slack_context>`,
86
+ ``,
87
+ `<user_request>`,
88
+ escapeXml(args.userMessage),
89
+ `</user_request>`,
90
+ ].join("\n");
91
+ }
59
92
  async function fetchThreadMessages(token, channel, threadTs, limit = DEFAULT_THREAD_REPLY_LIMIT) {
60
93
  const body = await slackApiGet(token, "conversations.replies", { channel, ts: threadTs, limit });
61
94
  return (body.messages ?? []).filter(isContextMessage);
@@ -75,16 +108,11 @@ export async function buildPromptWithSlackContext(args) {
75
108
  }
76
109
  const userNames = await resolveUserDisplayNames(args.token, messages.flatMap((message) => (message.user ? [message.user] : [])));
77
110
  const formattedMessages = formatContextMessages(messages, userNames);
78
- const contextLabel = args.threadTs
79
- ? "Slack thread context"
80
- : "Recent Slack channel messages";
81
- return [
82
- `## ${contextLabel}`,
83
- `Channel: ${args.channel}`,
84
- "",
85
- ...formattedMessages,
86
- "",
87
- "## User request",
88
- args.userMessage,
89
- ].join("\n");
111
+ return formatPromptWithSlackContext({
112
+ channel: args.channel,
113
+ source: args.threadTs ? "thread" : "channel",
114
+ messageCount: messages.length,
115
+ contextMessages: formattedMessages,
116
+ userMessage: args.userMessage,
117
+ });
90
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meetopenbot/slack",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Slack Events API ingress, simple agent replies, and thread delivery for OpenBot",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",