paperclip-plugin-mattermost 0.16.0 → 0.16.1
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/README.md +1 -1
- package/dist/manifest.js +1 -1
- package/dist/worker.js +26 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ PAPERCLIP_REF=<commit> node build.mjs # build for another Paperclip version
|
|
|
84
84
|
Bump `version` in `package.json` and `src/manifest.ts`, commit, then tag and push:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
git tag -a v0.16.
|
|
87
|
+
git tag -a v0.16.1 -m v0.16.1 && git push origin main v0.16.1
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
GitHub Actions builds, tests and publishes to npm through npm trusted publishing, so no npm token is involved.
|
package/dist/manifest.js
CHANGED
|
@@ -82,7 +82,7 @@ var route = (routeKey, method, path) => ({ routeKey, method, path, auth: "agent"
|
|
|
82
82
|
var manifest = {
|
|
83
83
|
id: "mattermost-bridge",
|
|
84
84
|
apiVersion: 1,
|
|
85
|
-
version: "0.16.
|
|
85
|
+
version: "0.16.1",
|
|
86
86
|
displayName: "Mattermost",
|
|
87
87
|
description: "Every agent becomes its own Mattermost bot. DM an agent or mention it in a channel and it answers in the thread, showing its steps as it works; follow-ups continue the conversation. Paperclip approvals arrive with Approve / Reject buttons.",
|
|
88
88
|
author: "Haseeb Azhar",
|
package/dist/worker.js
CHANGED
|
@@ -45032,7 +45032,9 @@ var Actions = class {
|
|
|
45032
45032
|
this.d = deps;
|
|
45033
45033
|
}
|
|
45034
45034
|
/** One route call. `params` are the route's path parameters, `input` its query or body. */
|
|
45035
|
-
|
|
45035
|
+
runId = null;
|
|
45036
|
+
async handle(agentId, routeKey, params, input2, runId = null) {
|
|
45037
|
+
this.runId = runId;
|
|
45036
45038
|
const bot = this.d.bot(agentId);
|
|
45037
45039
|
if (!bot) return bad(409, "You have no Mattermost bot in this company yet (your agent may be switched off in the plugin's settings).");
|
|
45038
45040
|
try {
|
|
@@ -45184,7 +45186,7 @@ var Actions = class {
|
|
|
45184
45186
|
const text2 = str3(input2.text);
|
|
45185
45187
|
if (!text2) return bad(400, "text is empty");
|
|
45186
45188
|
const ch = await this.channel(bot, str3(input2.channel));
|
|
45187
|
-
const threadId = str3(input2.threadId);
|
|
45189
|
+
const threadId = str3(input2.threadId) || await this.d.taskThread?.(agentId, this.runId, ch.id).catch(() => null) || "";
|
|
45188
45190
|
const waiting = await this.gate(agentId, canPost(text2), "post", `post in ~${ch.name}: "${text2.slice(0, 200)}"`, { channelId: ch.id, threadId, text: text2 });
|
|
45189
45191
|
if (waiting) return waiting;
|
|
45190
45192
|
return ok(await this.doPost(bot, ch.id, threadId, text2));
|
|
@@ -45207,7 +45209,8 @@ var Actions = class {
|
|
|
45207
45209
|
const verdict = canDm(await this.d.canTalk(user2.id, agentId));
|
|
45208
45210
|
if (!verdict.ok) return bad(403, `Not allowed: ${verdict.why}.`);
|
|
45209
45211
|
const channel2 = await bot.request("POST", "/channels/direct", [bot.botUserId, user2.id]);
|
|
45210
|
-
|
|
45212
|
+
const threadId = str3(input2.threadId) || await this.d.taskThread?.(agentId, this.runId, channel2.id).catch(() => null) || "";
|
|
45213
|
+
return ok(await this.doPost(bot, channel2.id, threadId, text2));
|
|
45211
45214
|
}
|
|
45212
45215
|
// ---- channels ----------------------------------------------------------------------
|
|
45213
45216
|
async created() {
|
|
@@ -46272,7 +46275,7 @@ var route = (routeKey, method, path3) => ({ routeKey, method, path: path3, auth:
|
|
|
46272
46275
|
var manifest = {
|
|
46273
46276
|
id: "mattermost-bridge",
|
|
46274
46277
|
apiVersion: 1,
|
|
46275
|
-
version: "0.16.
|
|
46278
|
+
version: "0.16.1",
|
|
46276
46279
|
displayName: "Mattermost",
|
|
46277
46280
|
description: "Every agent becomes its own Mattermost bot. DM an agent or mention it in a channel and it answers in the thread, showing its steps as it works; follow-ups continue the conversation. Paperclip approvals arrive with Approve / Reject buttons.",
|
|
46278
46281
|
author: "Haseeb Azhar",
|
|
@@ -46598,6 +46601,14 @@ var Tenant = class {
|
|
|
46598
46601
|
agents: () => roster.all().map((m) => ({ agentId: m.agentId, agentName: m.agentName, username: m.username, botUserId: m.botUserId })),
|
|
46599
46602
|
canTalk: async (userId, agentId) => !canTalk || canTalk(userId, agentId),
|
|
46600
46603
|
origin: (agentId) => bridge.activeThread(agentId),
|
|
46604
|
+
// The task this run works on (its execution or checkout run), and the thread it was asked for in.
|
|
46605
|
+
taskThread: async (agentId, runId, channelId) => {
|
|
46606
|
+
if (!runId) return null;
|
|
46607
|
+
const issues = await ctx.issues.list({ companyId, assigneeAgentId: agentId, limit: 200 });
|
|
46608
|
+
const issue2 = issues.find((i) => i.executionRunId === runId || i.checkoutRunId === runId);
|
|
46609
|
+
const at = issue2 ? await store.get(`issuethread:${issue2.id}`) : null;
|
|
46610
|
+
return at && at.channelId === channelId ? at.rootId : null;
|
|
46611
|
+
},
|
|
46601
46612
|
task: async (taskId) => await ctx.issues.get(taskId, companyId),
|
|
46602
46613
|
askApproval: async (req) => {
|
|
46603
46614
|
if (!paperclipUrl || !approvers.size) throw Object.assign(new Error("this needs a person's approval, and nobody can approve from Mattermost yet (the plugin needs its Paperclip public URL and approvers set)"), { status: 403 });
|
|
@@ -46668,9 +46679,9 @@ var Tenant = class {
|
|
|
46668
46679
|
return null;
|
|
46669
46680
|
}
|
|
46670
46681
|
/** An agent's call to one of the plugin's `/mm/...` routes. */
|
|
46671
|
-
async api(agentId, routeKey, params, input2) {
|
|
46682
|
+
async api(agentId, routeKey, params, input2, runId = null) {
|
|
46672
46683
|
if (!this.actions) return { status: 503, body: { error: `Mattermost is not connected for this company (${this.status})` } };
|
|
46673
|
-
return this.actions.handle(agentId, routeKey, params, input2);
|
|
46684
|
+
return this.actions.handle(agentId, routeKey, params, input2, runId);
|
|
46674
46685
|
}
|
|
46675
46686
|
/** The Agent computer plugin: an agent wants a person at its computer. Posted where the agent is working. */
|
|
46676
46687
|
async computerNeedsPerson(p) {
|
|
@@ -46826,6 +46837,14 @@ var plugin = definePlugin({
|
|
|
46826
46837
|
ctx.events.on("plugin.agent-computer.needs-person", (e) => quietly("could not post a computer help request", async () => {
|
|
46827
46838
|
await tenants.get(e.companyId)?.computerNeedsPerson(e.payload ?? {});
|
|
46828
46839
|
}));
|
|
46840
|
+
ctx.events.on("issue.created", (e) => quietly("could not link a task to its thread", async () => {
|
|
46841
|
+
const tenant = tenants.get(e.companyId);
|
|
46842
|
+
if (!tenant?.bridge || !e.entityId) return;
|
|
46843
|
+
const issue2 = await ctx.issues.get(e.entityId, e.companyId);
|
|
46844
|
+
const by = issue2?.createdByAgentId;
|
|
46845
|
+
const at = by ? tenant.bridge.activeThread(by) : null;
|
|
46846
|
+
if (at) await tenant.store().set(`issuethread:${e.entityId}`, at);
|
|
46847
|
+
}));
|
|
46829
46848
|
ctx.events.on("approval.decided", (e) => quietly("could not update approval", async () => {
|
|
46830
46849
|
if (e.entityId) await tenants.get(e.companyId)?.approvals?.decided(e.entityId);
|
|
46831
46850
|
}));
|
|
@@ -46865,7 +46884,7 @@ var plugin = definePlugin({
|
|
|
46865
46884
|
const messages = tenant.bridge ? await tenant.bridge.takeInbox(agentId) : [];
|
|
46866
46885
|
return { status: 200, body: { messages, note: messages.length ? "Written to you while you were working. Act on them now: they are not sent to you again." : "Nothing new." } };
|
|
46867
46886
|
}
|
|
46868
|
-
const res = await tenant.api(agentId, input2.routeKey, input2.params, { ...query, ...body });
|
|
46887
|
+
const res = await tenant.api(agentId, input2.routeKey, input2.params, { ...query, ...body }, input2.actor.runId ?? null);
|
|
46869
46888
|
if (tenant.bridge?.hasInbox(agentId) && res.body && typeof res.body === "object" && !Array.isArray(res.body)) {
|
|
46870
46889
|
res.body = { ...res.body, newMessages: await tenant.bridge.takeInbox(agentId) };
|
|
46871
46890
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paperclip-plugin-mattermost",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Paperclip agents in Mattermost: a bot per agent, live progress, files, approval and decision buttons, and per-person access, for each Paperclip company.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|