paperclip-plugin-telegram 0.2.1 → 0.2.2
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.
- package/dist/acp-bridge.d.ts +34 -0
- package/dist/acp-bridge.js +805 -0
- package/dist/acp-bridge.js.map +1 -0
- package/dist/adapter.d.ts +35 -0
- package/dist/adapter.js +75 -0
- package/dist/adapter.js.map +1 -0
- package/dist/command-registry.d.ts +3 -0
- package/dist/command-registry.js +273 -0
- package/dist/command-registry.js.map +1 -0
- package/dist/commands.d.ts +10 -0
- package/dist/commands.js +213 -0
- package/dist/commands.js.map +1 -0
- package/dist/constants.d.ts +44 -0
- package/dist/constants.js +48 -0
- package/dist/constants.js.map +1 -0
- package/dist/escalation.d.ts +41 -0
- package/dist/escalation.js +254 -0
- package/dist/escalation.js.map +1 -0
- package/dist/formatters.d.ts +13 -0
- package/dist/formatters.js +130 -0
- package/dist/formatters.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +3 -0
- package/dist/manifest.js +230 -0
- package/dist/manifest.js.map +1 -0
- package/dist/media-pipeline.d.ts +46 -0
- package/dist/media-pipeline.js +161 -0
- package/dist/media-pipeline.js.map +1 -0
- package/dist/telegram-api.d.ts +28 -0
- package/dist/telegram-api.js +147 -0
- package/dist/telegram-api.js.map +1 -0
- package/dist/watch-registry.d.ts +9 -0
- package/dist/watch-registry.js +272 -0
- package/dist/watch-registry.js.map +1 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +548 -0
- package/dist/worker.js.map +1 -0
- package/package.json +7 -3
- package/src/acp-bridge.ts +0 -1273
- package/src/adapter.ts +0 -129
- package/src/command-registry.ts +0 -482
- package/src/commands.ts +0 -346
- package/src/constants.ts +0 -51
- package/src/escalation.ts +0 -421
- package/src/formatters.ts +0 -148
- package/src/manifest.ts +0 -246
- package/src/media-pipeline.ts +0 -234
- package/src/telegram-api.ts +0 -202
- package/src/watch-registry.ts +0 -369
- package/src/worker.ts +0 -783
- package/tests/acp-bridge.test.ts +0 -314
- package/tests/command-registry.test.ts +0 -283
- package/tests/commands.test.ts +0 -213
- package/tests/escalation.test.ts +0 -550
- package/tests/formatters.test.ts +0 -185
- package/tests/media-pipeline.test.ts +0 -324
- package/tests/telegram-api.test.ts +0 -108
- package/tests/watch-registry.test.ts +0 -404
- package/tsconfig.json +0 -16
- /package/{src/index.ts → dist/index.d.ts} +0 -0
package/dist/commands.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { sendMessage, escapeMarkdownV2, sendChatAction } from "./telegram-api.js";
|
|
2
|
+
import { METRIC_NAMES } from "./constants.js";
|
|
3
|
+
import { handleAcpCommand } from "./acp-bridge.js";
|
|
4
|
+
export const BOT_COMMANDS = [
|
|
5
|
+
{ command: "status", description: "Company health: active agents, open issues" },
|
|
6
|
+
{ command: "issues", description: "List open issues (optionally by project)" },
|
|
7
|
+
{ command: "agents", description: "List agents with current status" },
|
|
8
|
+
{ command: "approve", description: "Approve a pending request by ID" },
|
|
9
|
+
{ command: "help", description: "Show available commands" },
|
|
10
|
+
{ command: "acp", description: "Manage agent sessions (spawn, status, cancel, close)" },
|
|
11
|
+
{ command: "commands", description: "Manage custom workflow commands (list, import, run, delete)" },
|
|
12
|
+
];
|
|
13
|
+
export async function handleCommand(ctx, token, chatId, command, args, messageThreadId, baseUrl) {
|
|
14
|
+
await ctx.metrics.write(METRIC_NAMES.commandsHandled, 1);
|
|
15
|
+
switch (command) {
|
|
16
|
+
case "status":
|
|
17
|
+
await handleStatus(ctx, token, chatId, messageThreadId);
|
|
18
|
+
break;
|
|
19
|
+
case "issues":
|
|
20
|
+
await handleIssues(ctx, token, chatId, args, messageThreadId);
|
|
21
|
+
break;
|
|
22
|
+
case "agents":
|
|
23
|
+
await handleAgents(ctx, token, chatId, messageThreadId);
|
|
24
|
+
break;
|
|
25
|
+
case "approve":
|
|
26
|
+
await handleApprove(ctx, token, chatId, args, messageThreadId, baseUrl);
|
|
27
|
+
break;
|
|
28
|
+
case "help":
|
|
29
|
+
await handleHelp(ctx, token, chatId, messageThreadId);
|
|
30
|
+
break;
|
|
31
|
+
case "connect":
|
|
32
|
+
await handleConnect(ctx, token, chatId, args, messageThreadId);
|
|
33
|
+
break;
|
|
34
|
+
case "connect-topic":
|
|
35
|
+
await handleConnectTopic(ctx, token, chatId, args, messageThreadId);
|
|
36
|
+
break;
|
|
37
|
+
case "acp":
|
|
38
|
+
await handleAcpCommand(ctx, token, chatId, args, messageThreadId);
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
await sendMessage(ctx, token, chatId, `Unknown command: /${command}. Try /help`, {
|
|
42
|
+
messageThreadId,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function handleStatus(ctx, token, chatId, messageThreadId) {
|
|
47
|
+
await sendChatAction(ctx, token, chatId);
|
|
48
|
+
try {
|
|
49
|
+
const companyId = await resolveCompanyId(ctx, chatId);
|
|
50
|
+
const agents = await ctx.agents.list({ companyId });
|
|
51
|
+
const activeAgents = agents.filter((a) => a.status === "active");
|
|
52
|
+
const issues = await ctx.issues.list({ companyId, limit: 10 });
|
|
53
|
+
const doneIssues = issues.filter((i) => i.status === "done");
|
|
54
|
+
const lines = [
|
|
55
|
+
escapeMarkdownV2("📊") + " *Paperclip Status*",
|
|
56
|
+
"",
|
|
57
|
+
`${escapeMarkdownV2("🤖")} Active agents: *${activeAgents.length}*/${escapeMarkdownV2(String(agents.length))}`,
|
|
58
|
+
`${escapeMarkdownV2("📋")} Recent issues: *${escapeMarkdownV2(String(issues.length))}* \\(${escapeMarkdownV2(String(doneIssues.length))} done\\)`,
|
|
59
|
+
];
|
|
60
|
+
await sendMessage(ctx, token, chatId, lines.join("\n"), {
|
|
61
|
+
parseMode: "MarkdownV2",
|
|
62
|
+
messageThreadId,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
await sendMessage(ctx, token, chatId, escapeMarkdownV2("📊") + " *Paperclip Status*\n\n" + escapeMarkdownV2("Could not fetch status. Make sure this chat is linked to a company with /connect."), {
|
|
67
|
+
parseMode: "MarkdownV2",
|
|
68
|
+
messageThreadId,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function handleIssues(ctx, token, chatId, projectFilter, messageThreadId) {
|
|
73
|
+
await sendChatAction(ctx, token, chatId);
|
|
74
|
+
try {
|
|
75
|
+
const companyId = await resolveCompanyId(ctx, chatId);
|
|
76
|
+
const issues = await ctx.issues.list({ companyId, limit: 10 });
|
|
77
|
+
const filtered = projectFilter
|
|
78
|
+
? issues.filter((i) => {
|
|
79
|
+
const projName = i.project?.name ?? "";
|
|
80
|
+
return projName.toLowerCase().includes(projectFilter.toLowerCase());
|
|
81
|
+
})
|
|
82
|
+
: issues;
|
|
83
|
+
if (filtered.length === 0) {
|
|
84
|
+
const filter = projectFilter ? ` for project "${projectFilter}"` : "";
|
|
85
|
+
await sendMessage(ctx, token, chatId, `No issues found${filter}.`, { messageThreadId });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const statusEmoji = { done: "✅", todo: "📋", in_progress: "🔄", backlog: "📥" };
|
|
89
|
+
const lines = [escapeMarkdownV2("📋") + " *Open Issues*", ""];
|
|
90
|
+
for (const issue of filtered) {
|
|
91
|
+
const emoji = statusEmoji[issue.status] ?? "📋";
|
|
92
|
+
const id = issue.identifier ?? issue.id;
|
|
93
|
+
lines.push(`${escapeMarkdownV2(emoji)} ${escapeMarkdownV2(id)} \\- ${escapeMarkdownV2(issue.title)}`);
|
|
94
|
+
}
|
|
95
|
+
await sendMessage(ctx, token, chatId, lines.join("\n"), {
|
|
96
|
+
parseMode: "MarkdownV2",
|
|
97
|
+
messageThreadId,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
const filter = projectFilter ? ` for project "${projectFilter}"` : "";
|
|
102
|
+
await sendMessage(ctx, token, chatId, `Could not fetch issues${filter}. Make sure this chat is linked with /connect.`, { messageThreadId });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function handleAgents(ctx, token, chatId, messageThreadId) {
|
|
106
|
+
await sendChatAction(ctx, token, chatId);
|
|
107
|
+
try {
|
|
108
|
+
const companyId = await resolveCompanyId(ctx, chatId);
|
|
109
|
+
const agents = await ctx.agents.list({ companyId });
|
|
110
|
+
if (agents.length === 0) {
|
|
111
|
+
await sendMessage(ctx, token, chatId, "No agents found.", { messageThreadId });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const statusEmoji = { active: "🟢", error: "🔴", paused: "🟡", idle: "⚪", running: "🔵" };
|
|
115
|
+
const lines = [escapeMarkdownV2("🤖") + " *Agents*", ""];
|
|
116
|
+
for (const agent of agents) {
|
|
117
|
+
const emoji = statusEmoji[agent.status] ?? "⚪";
|
|
118
|
+
lines.push(`${escapeMarkdownV2(emoji)} *${escapeMarkdownV2(agent.name)}* \\- ${escapeMarkdownV2(agent.status)}`);
|
|
119
|
+
}
|
|
120
|
+
await sendMessage(ctx, token, chatId, lines.join("\n"), {
|
|
121
|
+
parseMode: "MarkdownV2",
|
|
122
|
+
messageThreadId,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
await sendMessage(ctx, token, chatId, "Could not fetch agents. Make sure this chat is linked with /connect.", { messageThreadId });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function handleApprove(ctx, token, chatId, approvalId, messageThreadId, baseUrl = "http://localhost:3100") {
|
|
130
|
+
if (!approvalId.trim()) {
|
|
131
|
+
await sendMessage(ctx, token, chatId, "Usage: /approve <approval-id>", {
|
|
132
|
+
messageThreadId,
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
await ctx.http.fetch(`${baseUrl}/api/approvals/${approvalId.trim()}/approve`, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "Content-Type": "application/json" },
|
|
140
|
+
body: JSON.stringify({ decidedByUserId: `telegram:${chatId}` }),
|
|
141
|
+
});
|
|
142
|
+
await sendMessage(ctx, token, chatId, `${escapeMarkdownV2("✅")} *Approved*: \`${escapeMarkdownV2(approvalId.trim())}\``, { parseMode: "MarkdownV2", messageThreadId });
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
await sendMessage(ctx, token, chatId, `Failed to approve ${approvalId}: ${err instanceof Error ? err.message : String(err)}`, { messageThreadId });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function handleHelp(ctx, token, chatId, messageThreadId) {
|
|
149
|
+
const lines = [
|
|
150
|
+
escapeMarkdownV2("📎") + " *Paperclip Bot Commands*",
|
|
151
|
+
"",
|
|
152
|
+
...BOT_COMMANDS.map((cmd) => `/${escapeMarkdownV2(cmd.command)} \\- ${escapeMarkdownV2(cmd.description)}`),
|
|
153
|
+
"",
|
|
154
|
+
`/${escapeMarkdownV2("connect")} \\- ${escapeMarkdownV2("Link this chat to a Paperclip company")}`,
|
|
155
|
+
`/${escapeMarkdownV2("connect-topic")} \\- ${escapeMarkdownV2("Map a project to a forum topic")}`,
|
|
156
|
+
];
|
|
157
|
+
await sendMessage(ctx, token, chatId, lines.join("\n"), {
|
|
158
|
+
parseMode: "MarkdownV2",
|
|
159
|
+
messageThreadId,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function handleConnect(ctx, token, chatId, companyName, messageThreadId) {
|
|
163
|
+
if (!companyName.trim()) {
|
|
164
|
+
await sendMessage(ctx, token, chatId, "Usage: /connect <company-name>", {
|
|
165
|
+
messageThreadId,
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `chat_${chatId}` }, { companyName: companyName.trim(), linkedAt: new Date().toISOString() });
|
|
170
|
+
await sendMessage(ctx, token, chatId, `${escapeMarkdownV2("🔗")} ${escapeMarkdownV2("Linked this chat to company:")} *${escapeMarkdownV2(companyName.trim())}*`, { parseMode: "MarkdownV2", messageThreadId });
|
|
171
|
+
ctx.logger.info("Chat linked to company", { chatId, companyName: companyName.trim() });
|
|
172
|
+
}
|
|
173
|
+
export async function handleConnectTopic(ctx, token, chatId, args, messageThreadId) {
|
|
174
|
+
const parts = args.trim().split(/\s+/);
|
|
175
|
+
if (parts.length < 2) {
|
|
176
|
+
await sendMessage(ctx, token, chatId, "Usage: /connect\\-topic <project\\-name> <topic\\-id>", {
|
|
177
|
+
parseMode: "MarkdownV2",
|
|
178
|
+
messageThreadId,
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const topicId = parts.pop();
|
|
183
|
+
const projectName = parts.join(" ");
|
|
184
|
+
const existing = (await ctx.state.get({
|
|
185
|
+
scopeKind: "instance",
|
|
186
|
+
stateKey: `topic-map-${chatId}`,
|
|
187
|
+
}));
|
|
188
|
+
const topicMap = existing ?? {};
|
|
189
|
+
topicMap[projectName] = topicId;
|
|
190
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `topic-map-${chatId}` }, topicMap);
|
|
191
|
+
await sendMessage(ctx, token, chatId, `${escapeMarkdownV2("🔗")} ${escapeMarkdownV2(`Mapped project "${projectName}" to topic ${topicId}`)}`, { parseMode: "MarkdownV2", messageThreadId });
|
|
192
|
+
ctx.logger.info("Topic mapped", { chatId, projectName, topicId });
|
|
193
|
+
}
|
|
194
|
+
export async function getTopicForProject(ctx, chatId, projectName) {
|
|
195
|
+
if (!projectName)
|
|
196
|
+
return undefined;
|
|
197
|
+
const topicMap = (await ctx.state.get({
|
|
198
|
+
scopeKind: "instance",
|
|
199
|
+
stateKey: `topic-map-${chatId}`,
|
|
200
|
+
}));
|
|
201
|
+
if (!topicMap)
|
|
202
|
+
return undefined;
|
|
203
|
+
const topicId = topicMap[projectName];
|
|
204
|
+
return topicId ? Number(topicId) : undefined;
|
|
205
|
+
}
|
|
206
|
+
async function resolveCompanyId(ctx, chatId) {
|
|
207
|
+
const mapping = await ctx.state.get({
|
|
208
|
+
scopeKind: "instance",
|
|
209
|
+
stateKey: `chat_${chatId}`,
|
|
210
|
+
});
|
|
211
|
+
return mapping?.companyName ?? chatId;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAOnD,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,4CAA4C,EAAE;IAChF,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;IAC9E,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACrE,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACtE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAC3D,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,sDAAsD,EAAE;IACvF,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,6DAA6D,EAAE;CACpG,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,OAAe,EACf,IAAY,EACZ,eAAwB,EACxB,OAAgB;IAEhB,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAEzD,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ;YACX,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;YACxD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;YAC9D,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;YACxD,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;YACxE,MAAM;QACR,KAAK,MAAM;YACT,MAAM,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,SAAS;YACZ,MAAM,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,eAAe;YAClB,MAAM,kBAAkB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;YACpE,MAAM;QACR,KAAK,KAAK;YACR,MAAM,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC;YAClE,MAAM;QACR;YACE,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,OAAO,aAAa,EAAE;gBAC/E,eAAe;aAChB,CAAC,CAAC;IACP,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,eAAwB;IAExB,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAEpE,MAAM,KAAK,GAAG;YACZ,gBAAgB,CAAC,IAAI,CAAC,GAAG,qBAAqB;YAC9C,EAAE;YACF,GAAG,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,YAAY,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;YAC9G,GAAG,gBAAgB,CAAC,IAAI,CAAC,oBAAoB,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,UAAU;SAClJ,CAAC;QAEF,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtD,SAAS,EAAE,YAAY;YACvB,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,yBAAyB,GAAG,gBAAgB,CAAC,mFAAmF,CAAC,EAAE;YAChM,SAAS,EAAE,YAAY;YACvB,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,aAAqB,EACrB,eAAwB;IAExB,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,aAAa;YAC5B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAQ,EAAE,EAAE;gBACzB,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;gBACvC,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC;YACtE,CAAC,CAAC;YACJ,CAAC,CAAC,MAAM,CAAC;QAEX,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,iBAAiB,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,MAAM,GAAG,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;YACxF,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAA2B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACxG,MAAM,KAAK,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAC9D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;YAChD,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,EAAE,CAAC,QAAQ,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxG,CAAC;QAED,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtD,SAAS,EAAE,YAAY;YACvB,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,iBAAiB,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,yBAAyB,MAAM,gDAAgD,EAC/E,EAAE,eAAe,EAAE,CACpB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,eAAwB;IAExB,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAEpD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAA2B,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAClH,MAAM,KAAK,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,WAAW,EAAE,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnH,CAAC;QAED,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtD,SAAS,EAAE,YAAY;YACvB,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,sEAAsE,EACtE,EAAE,eAAe,EAAE,CACpB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,UAAkB,EAClB,eAAwB,EACxB,UAAkB,uBAAuB;IAEzC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;QACvB,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE;YACrE,eAAe;SAChB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAClB,GAAG,OAAO,kBAAkB,UAAU,CAAC,IAAI,EAAE,UAAU,EACvD;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,YAAY,MAAM,EAAE,EAAE,CAAC;SAChE,CACF,CAAC;QAEF,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,GAAG,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EACjF,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,CAC7C,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,qBAAqB,UAAU,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACtF,EAAE,eAAe,EAAE,CACpB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,eAAwB;IAExB,MAAM,KAAK,GAAG;QACZ,gBAAgB,CAAC,IAAI,CAAC,GAAG,2BAA2B;QACpD,EAAE;QACF,GAAG,YAAY,CAAC,GAAG,CACjB,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CACtF;QACD,EAAE;QACF,IAAI,gBAAgB,CAAC,SAAS,CAAC,QAAQ,gBAAgB,CAAC,uCAAuC,CAAC,EAAE;QAClG,IAAI,gBAAgB,CAAC,eAAe,CAAC,QAAQ,gBAAgB,CAAC,gCAAgC,CAAC,EAAE;KAClG,CAAC;IAEF,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACtD,SAAS,EAAE,YAAY;QACvB,eAAe;KAChB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,WAAmB,EACnB,eAAwB;IAExB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,EAAE;YACtE,eAAe;SAChB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CACjB,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,MAAM,EAAE,EAAE,EACrD,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CACxE,CAAC;IAEF,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,8BAA8B,CAAC,KAAK,gBAAgB,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,GAAG,EACzH,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,CAC7C,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAkB,EAClB,KAAa,EACb,MAAc,EACd,IAAY,EACZ,eAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,uDAAuD,EAAE;YAC7F,SAAS,EAAE,YAAY;YACvB,eAAe;SAChB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;IAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QACpC,SAAS,EAAE,UAAU;QACrB,QAAQ,EAAE,aAAa,MAAM,EAAE;KAChC,CAAC,CAAkC,CAAC;IAErC,MAAM,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC;IAEhC,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CACjB,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,MAAM,EAAE,EAAE,EAC1D,QAAQ,CACT,CAAC;IAEF,MAAM,WAAW,CACf,GAAG,EACH,KAAK,EACL,MAAM,EACN,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,mBAAmB,WAAW,cAAc,OAAO,EAAE,CAAC,EAAE,EACtG,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,CAC7C,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAkB,EAClB,MAAc,EACd,WAAoB;IAEpB,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QACpC,SAAS,EAAE,UAAU;QACrB,QAAQ,EAAE,aAAa,MAAM,EAAE;KAChC,CAAC,CAAkC,CAAC;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAkB,EAAE,MAAc;IAChE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QAClC,SAAS,EAAE,UAAU;QACrB,QAAQ,EAAE,QAAQ,MAAM,EAAE;KAC3B,CAAmC,CAAC;IACrC,OAAO,OAAO,EAAE,WAAW,IAAI,MAAM,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const PLUGIN_ID = "paperclip-plugin-telegram";
|
|
2
|
+
export declare const PLUGIN_VERSION = "0.2.0";
|
|
3
|
+
export declare const DEFAULT_CONFIG: {
|
|
4
|
+
readonly telegramBotTokenRef: "";
|
|
5
|
+
readonly defaultChatId: "";
|
|
6
|
+
readonly approvalsChatId: "";
|
|
7
|
+
readonly errorsChatId: "";
|
|
8
|
+
readonly paperclipBaseUrl: "http://localhost:3100";
|
|
9
|
+
readonly notifyOnIssueCreated: true;
|
|
10
|
+
readonly notifyOnIssueDone: true;
|
|
11
|
+
readonly notifyOnApprovalCreated: true;
|
|
12
|
+
readonly notifyOnAgentError: true;
|
|
13
|
+
readonly enableCommands: true;
|
|
14
|
+
readonly enableInbound: true;
|
|
15
|
+
readonly dailyDigestEnabled: false;
|
|
16
|
+
readonly dailyDigestTime: "09:00";
|
|
17
|
+
readonly topicRouting: false;
|
|
18
|
+
readonly escalationChatId: "";
|
|
19
|
+
readonly escalationTimeoutMs: 900000;
|
|
20
|
+
readonly escalationDefaultAction: "defer";
|
|
21
|
+
readonly escalationHoldMessage: "Let me check on that - I'll get back to you shortly.";
|
|
22
|
+
readonly briefAgentId: "";
|
|
23
|
+
readonly briefAgentChatIds: string[];
|
|
24
|
+
readonly transcriptionApiKeyRef: "";
|
|
25
|
+
readonly maxSuggestionsPerHourPerCompany: 10;
|
|
26
|
+
readonly watchDeduplicationWindowMs: 86400000;
|
|
27
|
+
};
|
|
28
|
+
export declare const MAX_AGENTS_PER_THREAD = 5;
|
|
29
|
+
export declare const MAX_CONVERSATION_TURNS = 50;
|
|
30
|
+
export declare const DEFAULT_CONVERSATION_TURNS = 10;
|
|
31
|
+
export declare const METRIC_NAMES: {
|
|
32
|
+
readonly sent: "telegram_notifications_sent";
|
|
33
|
+
readonly failed: "telegram_notification_failures";
|
|
34
|
+
readonly commandsHandled: "telegram_commands_handled";
|
|
35
|
+
readonly inboundRouted: "telegram_inbound_routed";
|
|
36
|
+
readonly escalationsCreated: "telegram_escalations_created";
|
|
37
|
+
readonly escalationsResolved: "telegram_escalations_resolved";
|
|
38
|
+
readonly escalationsTimedOut: "telegram_escalations_timed_out";
|
|
39
|
+
readonly mediaProcessed: "telegram_media_processed";
|
|
40
|
+
readonly commandsExecuted: "telegram_custom_commands_executed";
|
|
41
|
+
readonly suggestionsEmitted: "telegram_suggestions_emitted";
|
|
42
|
+
};
|
|
43
|
+
export declare const ACP_SPAWN_EVENT = "acp-spawn";
|
|
44
|
+
export declare const ACP_OUTPUT_EVENT = "plugin.paperclip-plugin-acp.output";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const PLUGIN_ID = "paperclip-plugin-telegram";
|
|
2
|
+
export const PLUGIN_VERSION = "0.2.0";
|
|
3
|
+
export const DEFAULT_CONFIG = {
|
|
4
|
+
telegramBotTokenRef: "",
|
|
5
|
+
defaultChatId: "",
|
|
6
|
+
approvalsChatId: "",
|
|
7
|
+
errorsChatId: "",
|
|
8
|
+
paperclipBaseUrl: "http://localhost:3100",
|
|
9
|
+
notifyOnIssueCreated: true,
|
|
10
|
+
notifyOnIssueDone: true,
|
|
11
|
+
notifyOnApprovalCreated: true,
|
|
12
|
+
notifyOnAgentError: true,
|
|
13
|
+
enableCommands: true,
|
|
14
|
+
enableInbound: true,
|
|
15
|
+
dailyDigestEnabled: false,
|
|
16
|
+
dailyDigestTime: "09:00",
|
|
17
|
+
topicRouting: false,
|
|
18
|
+
escalationChatId: "",
|
|
19
|
+
escalationTimeoutMs: 900000,
|
|
20
|
+
escalationDefaultAction: "defer",
|
|
21
|
+
escalationHoldMessage: "Let me check on that - I'll get back to you shortly.",
|
|
22
|
+
// Phase 3: Media Pipeline
|
|
23
|
+
briefAgentId: "",
|
|
24
|
+
briefAgentChatIds: [],
|
|
25
|
+
transcriptionApiKeyRef: "",
|
|
26
|
+
// Phase 5: Proactive Suggestions
|
|
27
|
+
maxSuggestionsPerHourPerCompany: 10,
|
|
28
|
+
watchDeduplicationWindowMs: 86400000, // 24h
|
|
29
|
+
};
|
|
30
|
+
export const MAX_AGENTS_PER_THREAD = 5;
|
|
31
|
+
export const MAX_CONVERSATION_TURNS = 50;
|
|
32
|
+
export const DEFAULT_CONVERSATION_TURNS = 10;
|
|
33
|
+
export const METRIC_NAMES = {
|
|
34
|
+
sent: "telegram_notifications_sent",
|
|
35
|
+
failed: "telegram_notification_failures",
|
|
36
|
+
commandsHandled: "telegram_commands_handled",
|
|
37
|
+
inboundRouted: "telegram_inbound_routed",
|
|
38
|
+
escalationsCreated: "telegram_escalations_created",
|
|
39
|
+
escalationsResolved: "telegram_escalations_resolved",
|
|
40
|
+
escalationsTimedOut: "telegram_escalations_timed_out",
|
|
41
|
+
mediaProcessed: "telegram_media_processed",
|
|
42
|
+
commandsExecuted: "telegram_custom_commands_executed",
|
|
43
|
+
suggestionsEmitted: "telegram_suggestions_emitted",
|
|
44
|
+
};
|
|
45
|
+
// Cross-plugin ACP event names
|
|
46
|
+
export const ACP_SPAWN_EVENT = "acp-spawn";
|
|
47
|
+
export const ACP_OUTPUT_EVENT = "plugin.paperclip-plugin-acp.output";
|
|
48
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,2BAA2B,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,mBAAmB,EAAE,EAAE;IACvB,aAAa,EAAE,EAAE;IACjB,eAAe,EAAE,EAAE;IACnB,YAAY,EAAE,EAAE;IAChB,gBAAgB,EAAE,uBAAuB;IACzC,oBAAoB,EAAE,IAAI;IAC1B,iBAAiB,EAAE,IAAI;IACvB,uBAAuB,EAAE,IAAI;IAC7B,kBAAkB,EAAE,IAAI;IACxB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;IACnB,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,OAAO;IACxB,YAAY,EAAE,KAAK;IACnB,gBAAgB,EAAE,EAAE;IACpB,mBAAmB,EAAE,MAAM;IAC3B,uBAAuB,EAAE,OAAO;IAChC,qBAAqB,EAAE,sDAAsD;IAC7E,0BAA0B;IAC1B,YAAY,EAAE,EAAE;IAChB,iBAAiB,EAAE,EAAc;IACjC,sBAAsB,EAAE,EAAE;IAC1B,iCAAiC;IACjC,+BAA+B,EAAE,EAAE;IACnC,0BAA0B,EAAE,QAAQ,EAAE,MAAM;CACpC,CAAC;AAEX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,6BAA6B;IACnC,MAAM,EAAE,gCAAgC;IACxC,eAAe,EAAE,2BAA2B;IAC5C,aAAa,EAAE,yBAAyB;IACxC,kBAAkB,EAAE,8BAA8B;IAClD,mBAAmB,EAAE,+BAA+B;IACpD,mBAAmB,EAAE,gCAAgC;IACrD,cAAc,EAAE,0BAA0B;IAC1C,gBAAgB,EAAE,mCAAmC;IACrD,kBAAkB,EAAE,8BAA8B;CAC1C,CAAC;AAEX,+BAA+B;AAC/B,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PluginContext } from "@paperclipai/plugin-sdk";
|
|
2
|
+
export type EscalationReason = "low_confidence" | "explicit_request" | "policy_violation" | "unknown_intent";
|
|
3
|
+
export type EscalationEvent = {
|
|
4
|
+
escalationId: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
companyId: string;
|
|
7
|
+
reason: EscalationReason;
|
|
8
|
+
context: {
|
|
9
|
+
conversationHistory: Array<{
|
|
10
|
+
role: string;
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
agentReasoning: string;
|
|
14
|
+
suggestedActions: string[];
|
|
15
|
+
suggestedReply?: string;
|
|
16
|
+
confidenceScore?: number;
|
|
17
|
+
};
|
|
18
|
+
timeout: {
|
|
19
|
+
durationMs: number;
|
|
20
|
+
defaultAction: "defer" | "auto_reply" | "close";
|
|
21
|
+
};
|
|
22
|
+
originChatId?: string;
|
|
23
|
+
originThreadId?: string;
|
|
24
|
+
originMessageId?: string;
|
|
25
|
+
transport?: "native" | "acp";
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
};
|
|
28
|
+
export type EscalationResponse = {
|
|
29
|
+
escalationId: string;
|
|
30
|
+
responderId: string;
|
|
31
|
+
responseText: string;
|
|
32
|
+
action: "reply_to_customer" | "override_suggested" | "dismiss";
|
|
33
|
+
};
|
|
34
|
+
export declare class EscalationManager {
|
|
35
|
+
create(ctx: PluginContext, token: string, event: EscalationEvent, escalationChatId: string): Promise<void>;
|
|
36
|
+
handleCallback(ctx: PluginContext, token: string, action: string, escalationId: string, actor: string, callbackQueryId: string, chatId: string | null, messageId: number | undefined): Promise<void>;
|
|
37
|
+
respond(ctx: PluginContext, token: string, escalationId: string, response: EscalationResponse): Promise<void>;
|
|
38
|
+
private resolve;
|
|
39
|
+
checkTimeouts(ctx: PluginContext, token: string): Promise<void>;
|
|
40
|
+
private removePending;
|
|
41
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { sendMessage, editMessage, escapeMarkdownV2, truncateAtWord } from "./telegram-api.js";
|
|
2
|
+
const REASON_LABELS = {
|
|
3
|
+
low_confidence: "Low Confidence",
|
|
4
|
+
explicit_request: "User Requested Human",
|
|
5
|
+
policy_violation: "Policy Violation",
|
|
6
|
+
unknown_intent: "Unknown Intent",
|
|
7
|
+
};
|
|
8
|
+
function esc(s) {
|
|
9
|
+
return escapeMarkdownV2(s);
|
|
10
|
+
}
|
|
11
|
+
export class EscalationManager {
|
|
12
|
+
async create(ctx, token, event, escalationChatId) {
|
|
13
|
+
const reasonLabel = REASON_LABELS[event.reason] ?? event.reason;
|
|
14
|
+
const confidence = event.context.confidenceScore != null
|
|
15
|
+
? ` \\(${esc(String(Math.round(event.context.confidenceScore * 100)))}%\\)`
|
|
16
|
+
: "";
|
|
17
|
+
const lines = [
|
|
18
|
+
`${esc("\u26a0\ufe0f")} *Escalation* \\- ${esc(reasonLabel)}${confidence}`,
|
|
19
|
+
"",
|
|
20
|
+
`*Agent:* ${esc(event.agentId)}`,
|
|
21
|
+
`*Reason:* ${esc(event.context.agentReasoning ? truncateAtWord(event.context.agentReasoning, 500) : "No details provided")}`,
|
|
22
|
+
];
|
|
23
|
+
if (event.context.suggestedActions.length > 0) {
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push("*Suggested actions:*");
|
|
26
|
+
for (const action of event.context.suggestedActions.slice(0, 5)) {
|
|
27
|
+
lines.push(` ${esc("-")} ${esc(action)}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (event.context.suggestedReply) {
|
|
31
|
+
lines.push("");
|
|
32
|
+
lines.push("*Suggested reply:*");
|
|
33
|
+
lines.push(`${esc(">")} ${esc(truncateAtWord(event.context.suggestedReply, 300))}`);
|
|
34
|
+
}
|
|
35
|
+
lines.push("");
|
|
36
|
+
lines.push(`ID: \`${esc(event.escalationId)}\``);
|
|
37
|
+
const buttons = [];
|
|
38
|
+
if (event.context.suggestedReply) {
|
|
39
|
+
buttons.push([
|
|
40
|
+
{ text: "Send Suggested Reply", callback_data: `esc_suggested_${event.escalationId}` },
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
43
|
+
buttons.push([
|
|
44
|
+
{ text: "Reply", callback_data: `esc_reply_${event.escalationId}` },
|
|
45
|
+
{ text: "Override", callback_data: `esc_override_${event.escalationId}` },
|
|
46
|
+
{ text: "Dismiss", callback_data: `esc_dismiss_${event.escalationId}` },
|
|
47
|
+
]);
|
|
48
|
+
const messageId = await sendMessage(ctx, token, escalationChatId, lines.join("\n"), {
|
|
49
|
+
parseMode: "MarkdownV2",
|
|
50
|
+
inlineKeyboard: buttons,
|
|
51
|
+
});
|
|
52
|
+
if (!messageId) {
|
|
53
|
+
ctx.logger.error("Failed to send escalation message", { escalationId: event.escalationId });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const timeoutAt = new Date(Date.now() + event.timeout.durationMs).toISOString();
|
|
57
|
+
const stored = {
|
|
58
|
+
escalationId: event.escalationId,
|
|
59
|
+
agentId: event.agentId,
|
|
60
|
+
companyId: event.companyId,
|
|
61
|
+
reason: event.reason,
|
|
62
|
+
agentReasoning: event.context.agentReasoning,
|
|
63
|
+
suggestedReply: event.context.suggestedReply,
|
|
64
|
+
suggestedActions: event.context.suggestedActions,
|
|
65
|
+
confidenceScore: event.context.confidenceScore,
|
|
66
|
+
originChatId: event.originChatId,
|
|
67
|
+
originThreadId: event.originThreadId,
|
|
68
|
+
originMessageId: event.originMessageId,
|
|
69
|
+
escalationChatId,
|
|
70
|
+
escalationMessageId: String(messageId),
|
|
71
|
+
status: "pending",
|
|
72
|
+
createdAt: new Date().toISOString(),
|
|
73
|
+
timeoutAt,
|
|
74
|
+
defaultAction: event.timeout.defaultAction,
|
|
75
|
+
transport: event.transport,
|
|
76
|
+
sessionId: event.sessionId,
|
|
77
|
+
};
|
|
78
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `escalation_${event.escalationId}` }, stored);
|
|
79
|
+
// Map the escalation message back so replies can be routed
|
|
80
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `msg_${escalationChatId}_${messageId}` }, {
|
|
81
|
+
entityId: event.escalationId,
|
|
82
|
+
entityType: "escalation",
|
|
83
|
+
companyId: event.companyId,
|
|
84
|
+
eventType: "escalation.created",
|
|
85
|
+
});
|
|
86
|
+
// Track pending escalation IDs for timeout checks
|
|
87
|
+
const pendingIds = await ctx.state.get({
|
|
88
|
+
scopeKind: "instance",
|
|
89
|
+
stateKey: "escalation_pending_ids",
|
|
90
|
+
}) ?? [];
|
|
91
|
+
pendingIds.push(event.escalationId);
|
|
92
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: "escalation_pending_ids" }, pendingIds);
|
|
93
|
+
ctx.logger.info("Escalation created", {
|
|
94
|
+
escalationId: event.escalationId,
|
|
95
|
+
reason: event.reason,
|
|
96
|
+
timeoutAt,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async handleCallback(ctx, token, action, escalationId, actor, callbackQueryId, chatId, messageId) {
|
|
100
|
+
const stored = await ctx.state.get({
|
|
101
|
+
scopeKind: "instance",
|
|
102
|
+
stateKey: `escalation_${escalationId}`,
|
|
103
|
+
});
|
|
104
|
+
if (!stored || stored.status !== "pending") {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
switch (action) {
|
|
108
|
+
case "suggested": {
|
|
109
|
+
if (!stored.suggestedReply)
|
|
110
|
+
break;
|
|
111
|
+
await this.resolve(ctx, token, stored, {
|
|
112
|
+
escalationId,
|
|
113
|
+
responderId: `telegram:${actor}`,
|
|
114
|
+
responseText: stored.suggestedReply,
|
|
115
|
+
action: "reply_to_customer",
|
|
116
|
+
});
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "reply": {
|
|
120
|
+
if (chatId && messageId) {
|
|
121
|
+
await editMessage(ctx, token, chatId, messageId, `${esc("\u26a0\ufe0f")} *Escalation* \\- *Awaiting your reply*\n\n${esc("Reply to this message with your response to the customer.")}`, { parseMode: "MarkdownV2" });
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "dismiss": {
|
|
126
|
+
await this.resolve(ctx, token, stored, {
|
|
127
|
+
escalationId,
|
|
128
|
+
responderId: `telegram:${actor}`,
|
|
129
|
+
responseText: "",
|
|
130
|
+
action: "dismiss",
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "override": {
|
|
135
|
+
if (chatId && messageId) {
|
|
136
|
+
await editMessage(ctx, token, chatId, messageId, `${esc("\u26a0\ufe0f")} *Escalation* \\- *Override mode*\n\n${esc("Reply to this message with your custom response.")}`, { parseMode: "MarkdownV2" });
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async respond(ctx, token, escalationId, response) {
|
|
143
|
+
const stored = await ctx.state.get({
|
|
144
|
+
scopeKind: "instance",
|
|
145
|
+
stateKey: `escalation_${escalationId}`,
|
|
146
|
+
});
|
|
147
|
+
if (!stored || stored.status !== "pending") {
|
|
148
|
+
ctx.logger.warn("Escalation respond called for non-pending escalation", { escalationId });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
await this.resolve(ctx, token, stored, response);
|
|
152
|
+
}
|
|
153
|
+
async resolve(ctx, token, stored, response) {
|
|
154
|
+
stored.status = "resolved";
|
|
155
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `escalation_${stored.escalationId}` }, stored);
|
|
156
|
+
await this.removePending(ctx, stored.escalationId);
|
|
157
|
+
const statusLabel = response.action === "dismiss" ? "Dismissed" : "Resolved";
|
|
158
|
+
await editMessage(ctx, token, stored.escalationChatId, Number(stored.escalationMessageId), `${esc("\u2705")} *Escalation ${statusLabel}* by ${esc(response.responderId)}\n\nID: \`${esc(stored.escalationId)}\``, { parseMode: "MarkdownV2" });
|
|
159
|
+
// Route reply back via the correct transport
|
|
160
|
+
if (response.action === "reply_to_customer" && response.responseText) {
|
|
161
|
+
if (stored.transport === "native" && stored.sessionId) {
|
|
162
|
+
// Route back through native agent session
|
|
163
|
+
try {
|
|
164
|
+
await ctx.agents.sessions.sendMessage(stored.sessionId, stored.companyId, {
|
|
165
|
+
prompt: `[Human escalation response] ${response.responseText}`,
|
|
166
|
+
reason: "escalation_reply",
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
ctx.logger.error("Failed to route escalation reply to native session", { error: String(err) });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (stored.transport === "acp" && stored.sessionId) {
|
|
174
|
+
// Route back via ACP event
|
|
175
|
+
ctx.events.emit("acp-spawn", stored.companyId, {
|
|
176
|
+
type: "message",
|
|
177
|
+
sessionId: stored.sessionId,
|
|
178
|
+
text: `[Human escalation response] ${response.responseText}`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// Also send to the originating Telegram chat if available
|
|
182
|
+
if (stored.originChatId) {
|
|
183
|
+
await sendMessage(ctx, token, stored.originChatId, esc(response.responseText), {
|
|
184
|
+
parseMode: "MarkdownV2",
|
|
185
|
+
messageThreadId: stored.originThreadId ? Number(stored.originThreadId) : undefined,
|
|
186
|
+
replyToMessageId: stored.originMessageId ? Number(stored.originMessageId) : undefined,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Emit resolution event - companyId is SECOND arg
|
|
191
|
+
ctx.events.emit("escalation.resolved", stored.companyId, {
|
|
192
|
+
escalationId: stored.escalationId,
|
|
193
|
+
agentId: stored.agentId,
|
|
194
|
+
responderId: response.responderId,
|
|
195
|
+
responseText: response.responseText,
|
|
196
|
+
action: response.action,
|
|
197
|
+
});
|
|
198
|
+
ctx.logger.info("Escalation resolved", {
|
|
199
|
+
escalationId: stored.escalationId,
|
|
200
|
+
action: response.action,
|
|
201
|
+
responderId: response.responderId,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async checkTimeouts(ctx, token) {
|
|
205
|
+
const pendingIds = await ctx.state.get({
|
|
206
|
+
scopeKind: "instance",
|
|
207
|
+
stateKey: "escalation_pending_ids",
|
|
208
|
+
}) ?? [];
|
|
209
|
+
if (pendingIds.length === 0)
|
|
210
|
+
return;
|
|
211
|
+
const now = Date.now();
|
|
212
|
+
for (const escalationId of pendingIds) {
|
|
213
|
+
const stored = await ctx.state.get({
|
|
214
|
+
scopeKind: "instance",
|
|
215
|
+
stateKey: `escalation_${escalationId}`,
|
|
216
|
+
});
|
|
217
|
+
if (!stored || stored.status !== "pending") {
|
|
218
|
+
await this.removePending(ctx, escalationId);
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const timeoutAt = new Date(stored.timeoutAt).getTime();
|
|
222
|
+
if (now < timeoutAt)
|
|
223
|
+
continue;
|
|
224
|
+
ctx.logger.info("Escalation timed out", { escalationId, defaultAction: stored.defaultAction });
|
|
225
|
+
stored.status = "timed_out";
|
|
226
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: `escalation_${escalationId}` }, stored);
|
|
227
|
+
await this.removePending(ctx, escalationId);
|
|
228
|
+
await editMessage(ctx, token, stored.escalationChatId, Number(stored.escalationMessageId), `${esc("\u23f0")} *Escalation Timed Out*\n\nDefault action: ${esc(stored.defaultAction)}\nID: \`${esc(escalationId)}\``, { parseMode: "MarkdownV2" });
|
|
229
|
+
// Emit timeout event - companyId is SECOND arg
|
|
230
|
+
ctx.events.emit("escalation.timed_out", stored.companyId, {
|
|
231
|
+
escalationId,
|
|
232
|
+
agentId: stored.agentId,
|
|
233
|
+
defaultAction: stored.defaultAction,
|
|
234
|
+
suggestedReply: stored.suggestedReply,
|
|
235
|
+
});
|
|
236
|
+
if (stored.defaultAction === "auto_reply" && stored.suggestedReply && stored.originChatId) {
|
|
237
|
+
await sendMessage(ctx, token, stored.originChatId, esc(stored.suggestedReply), {
|
|
238
|
+
parseMode: "MarkdownV2",
|
|
239
|
+
messageThreadId: stored.originThreadId ? Number(stored.originThreadId) : undefined,
|
|
240
|
+
replyToMessageId: stored.originMessageId ? Number(stored.originMessageId) : undefined,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async removePending(ctx, escalationId) {
|
|
246
|
+
const pendingIds = await ctx.state.get({
|
|
247
|
+
scopeKind: "instance",
|
|
248
|
+
stateKey: "escalation_pending_ids",
|
|
249
|
+
}) ?? [];
|
|
250
|
+
const updated = pendingIds.filter((id) => id !== escalationId);
|
|
251
|
+
await ctx.state.set({ scopeKind: "instance", stateKey: "escalation_pending_ids" }, updated);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=escalation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalation.js","sourceRoot":"","sources":["../src/escalation.ts"],"names":[],"mappings":"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"}
|