@open-everywhere/provider-slack 0.1.5 → 0.3.0

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.
Files changed (68) hide show
  1. package/NOTICE +9 -9
  2. package/README.md +1 -1
  3. package/agent/app-manifest.ts +44 -9
  4. package/agent/channels/slack-commands.ts +9 -5
  5. package/agent/channels/slack-events.ts +76 -13
  6. package/agent/channels/slack-front.ts +4 -80
  7. package/agent/channels/slack-post-arm.ts +1 -42
  8. package/agent/channels/slack-task-card.ts +182 -0
  9. package/agent/channels/slack.ts +518 -468
  10. package/agent/contributions.ts +1 -1
  11. package/agent/docs-generated.ts +1 -1
  12. package/agent/ops.ts +20 -2
  13. package/agent/setup/claim.ts +16 -1
  14. package/agent/setup/eve-credentials.ts +10 -2
  15. package/agent/setup/page.ts +79 -14
  16. package/agent/surface-parity.ts +0 -6
  17. package/dist/agent/app-manifest.d.ts +20 -4
  18. package/dist/agent/app-manifest.d.ts.map +1 -1
  19. package/dist/agent/app-manifest.js +29 -6
  20. package/dist/agent/app-manifest.js.map +1 -1
  21. package/dist/agent/channels/slack-commands.d.ts.map +1 -1
  22. package/dist/agent/channels/slack-commands.js +9 -6
  23. package/dist/agent/channels/slack-commands.js.map +1 -1
  24. package/dist/agent/channels/slack-events.d.ts +28 -6
  25. package/dist/agent/channels/slack-events.d.ts.map +1 -1
  26. package/dist/agent/channels/slack-events.js +74 -14
  27. package/dist/agent/channels/slack-events.js.map +1 -1
  28. package/dist/agent/channels/slack-front.d.ts +1 -15
  29. package/dist/agent/channels/slack-front.d.ts.map +1 -1
  30. package/dist/agent/channels/slack-front.js +4 -62
  31. package/dist/agent/channels/slack-front.js.map +1 -1
  32. package/dist/agent/channels/slack-post-arm.d.ts +1 -8
  33. package/dist/agent/channels/slack-post-arm.d.ts.map +1 -1
  34. package/dist/agent/channels/slack-post-arm.js +1 -40
  35. package/dist/agent/channels/slack-post-arm.js.map +1 -1
  36. package/dist/agent/channels/slack-task-card.d.ts +38 -0
  37. package/dist/agent/channels/slack-task-card.d.ts.map +1 -0
  38. package/dist/agent/channels/slack-task-card.js +156 -0
  39. package/dist/agent/channels/slack-task-card.js.map +1 -0
  40. package/dist/agent/channels/slack.d.ts.map +1 -1
  41. package/dist/agent/channels/slack.js +516 -466
  42. package/dist/agent/channels/slack.js.map +1 -1
  43. package/dist/agent/contributions.d.ts +1 -1
  44. package/dist/agent/contributions.d.ts.map +1 -1
  45. package/dist/agent/contributions.js +1 -1
  46. package/dist/agent/contributions.js.map +1 -1
  47. package/dist/agent/docs-generated.js +1 -1
  48. package/dist/agent/docs-generated.js.map +1 -1
  49. package/dist/agent/ops.d.ts +5 -0
  50. package/dist/agent/ops.d.ts.map +1 -1
  51. package/dist/agent/ops.js +13 -2
  52. package/dist/agent/ops.js.map +1 -1
  53. package/dist/agent/setup/claim.d.ts.map +1 -1
  54. package/dist/agent/setup/claim.js +15 -2
  55. package/dist/agent/setup/claim.js.map +1 -1
  56. package/dist/agent/setup/eve-credentials.d.ts +9 -2
  57. package/dist/agent/setup/eve-credentials.d.ts.map +1 -1
  58. package/dist/agent/setup/eve-credentials.js +9 -1
  59. package/dist/agent/setup/eve-credentials.js.map +1 -1
  60. package/dist/agent/setup/page.d.ts +2 -0
  61. package/dist/agent/setup/page.d.ts.map +1 -1
  62. package/dist/agent/setup/page.js +71 -15
  63. package/dist/agent/setup/page.js.map +1 -1
  64. package/dist/agent/surface-parity.d.ts.map +1 -1
  65. package/dist/agent/surface-parity.js +0 -6
  66. package/dist/agent/surface-parity.js.map +1 -1
  67. package/package.json +10 -8
  68. package/agent/channels/slack-approval-card.ts +0 -275
@@ -0,0 +1,156 @@
1
+ // THE TASK CARD'S CONFIDENTIALITY SEAM (OPE-2255).
2
+ //
3
+ // eve 0.69 posts a live TASK CARD for every turn that starts a task: one message per turn, one row
4
+ // per task, updated in place. OE adopts eve's own card (Tommy's principle: native first), so this
5
+ // file draws nothing itself. Every card still comes from eve's `renderDefaultSlackTaskCard` through
6
+ // `next`. This file only changes the VIEW that eve draws from.
7
+ //
8
+ // WHY A SEAM. An agent task's row title is the worker BRIEF (`<agent>: <brief>`, or the brief alone
9
+ // for a call to the agent's own copy). The model writes that brief from the whole session context.
10
+ // On a unified domain seat, that context can hold another conversation, for example a DM. eve gates
11
+ // only a failure line and a blocker's label on the room's audience, and eve's `private` audience
12
+ // covers private channels and group DMs too, which have several readers. The title, the
13
+ // notification `text` (`Working on 1 task: <the whole brief>`, not cut) and a completed row's
14
+ // `Done in Xs: <first sentence of the worker's reply>` reach a public channel unchanged
15
+ // (OPE-2246 Q7, measured on a real `actions.requested`).
16
+ //
17
+ // THE RULE. OE cannot trace the provenance of one model-written string. So the rule is on the ROOM,
18
+ // and it fails closed:
19
+ // * A task row shows its own title only in a 1:1 DM whose only human is the turn's own caller.
20
+ // * In every other room (a public channel, a private channel, a group DM, an unknown room) the row
21
+ // shows a generic label made from the task's NAME only. The name is code, not model text. A
22
+ // blocked row there keeps only the KIND of its blocker (`Waiting for a response`), never the
23
+ // request's prompt or the connection's name.
24
+ // * A completed row NEVER shows the worker's result excerpt, in any room. That excerpt bypasses
25
+ // `approvals/review-surface.ts`, which frames a delegated verdict as a model opinion. eve keeps
26
+ // the `Done in Xs` line, so the card still says the task finished.
27
+ // eve builds the notification `text` from the row titles, so the same redaction covers it.
28
+ //
29
+ // WHY A SESSION STATE SLOT. The `taskCard` hook is pure and synchronous, and its view carries no room.
30
+ // The view's `turnId` is no key either: eve numbers turns per session (`turn_<sequence>`), so two
31
+ // sessions in one process share turn ids. eve dispatches each session event inside that session's
32
+ // eve context, and `withTaskCards` writes the card inside the same dispatch. So each tracked event
33
+ // handler below records the room in a `defineState` slot, which is keyed to the session and
34
+ // durable, and the `taskCard` link reads back the LATEST room this session recorded. Most writes
35
+ // follow the handler of their own event. One does not: on `task.started`, eve's `closeSettledCard`
36
+ // writes the closing card BEFORE the handler runs, so that write reads the room an earlier event of
37
+ // the session recorded. That is safe because a session's channel and its DM partner do not change.
38
+ // No slot, or no eve context, reads as a shared room: the card then shows the generic label. It
39
+ // never shows the brief by accident.
40
+ import { defineState } from "eve/context";
41
+ /** The label for a call to the agent's own copy, whose eve name (`agent`) says nothing to a reader. */
42
+ export const GENERIC_SELF_TASK_LABEL = "Delegated task";
43
+ /** eve's tool name for a call to the agent's own copy (`tools/framework/agent-contract.js`). */
44
+ const AGENT_SELF_TOOL_NAME = "agent";
45
+ /**
46
+ * Decide the room. A 1:1 DM needs all three facts: the caller's auth says `channel_type: "im"`, the
47
+ * auth names the SAME channel the card posts to, and eve does not call the room public. Anything
48
+ * else, a missing fact included, is a shared room. Pure and total.
49
+ */
50
+ export function taskCardRoomOf(facts) {
51
+ const channelId = facts?.state?.channelId;
52
+ const attrs = facts?.attributes;
53
+ if (typeof channelId !== "string" || channelId === "" || attrs === null || attrs === undefined)
54
+ return "shared";
55
+ if (attrs.channel_type !== "im")
56
+ return "shared";
57
+ if (attrs.channel_id !== channelId)
58
+ return "shared";
59
+ if (facts?.state?.audience === "public")
60
+ return "shared";
61
+ return "direct-message";
62
+ }
63
+ /** A task's generic label: its name in words, never its brief or its tool's start label. */
64
+ export function genericTaskLabel(task) {
65
+ if (task.kind === "agent" && task.name === AGENT_SELF_TOOL_NAME)
66
+ return GENERIC_SELF_TASK_LABEL;
67
+ // eve's own `displayTitle` shape: the last `__` segment, words split on case, `_` and `-`.
68
+ const segment = task.name.split("__").findLast((s) => s !== "") ?? task.name;
69
+ const words = segment
70
+ .replace(/([a-z0-9])([A-Z])/gu, "$1 $2")
71
+ .split(/[\s_-]+/u)
72
+ .filter((w) => w !== "")
73
+ .map((w) => (w.length > 1 && w === w.toUpperCase() ? w : w.toLowerCase()));
74
+ if (words.length === 0)
75
+ return GENERIC_SELF_TASK_LABEL;
76
+ const text = words.join(" ");
77
+ return text.charAt(0).toUpperCase() + text.slice(1);
78
+ }
79
+ /**
80
+ * The view eve draws for this room. Every row loses its result excerpt. In a shared room every row
81
+ * also loses its title for the generic label, and a blocked row loses its blocker's label. A pure
82
+ * function: the input view is never changed.
83
+ */
84
+ export function confidentialTaskCardView(view, room) {
85
+ const tasks = view.tasks.map((task) => {
86
+ const { summary: _summary, blockedOn, ...rest } = task;
87
+ if (room === "direct-message")
88
+ return blockedOn === undefined ? rest : { ...rest, blockedOn };
89
+ const redacted = { ...rest, title: genericTaskLabel(task) };
90
+ return blockedOn === undefined ? redacted : { ...redacted, blockedOn: { kind: blockedOn.kind } };
91
+ });
92
+ return { ...view, tasks };
93
+ }
94
+ const roomSlot = defineState("open-everywhere.slack-task-card-room", () => null);
95
+ /** Record the room for this session's next card write. Outside an eve context it does nothing. */
96
+ function recordTaskCardRoom(channel, ctx) {
97
+ const attributes = ctx
98
+ ?.session?.auth?.current?.attributes;
99
+ const state = channel.state;
100
+ const room = taskCardRoomOf({ attributes, state });
101
+ try {
102
+ roomSlot.update(() => room);
103
+ }
104
+ catch {
105
+ // No eve context: nothing to record. The card then reads no room and shows the generic label.
106
+ }
107
+ }
108
+ /** The room this session recorded, or `shared` when none is readable. */
109
+ function readTaskCardRoom() {
110
+ try {
111
+ return roomSlot.get() ?? "shared";
112
+ }
113
+ catch {
114
+ return "shared";
115
+ }
116
+ }
117
+ /** The `taskCard` link: redact the view for the recorded room, then let eve draw its default card. */
118
+ export function confidentialTaskCard(view, next, room = readTaskCardRoom()) {
119
+ return next(confidentialTaskCardView(view, room));
120
+ }
121
+ // The events after which eve writes a card: eve's `TRACKED_EVENTS` in
122
+ // `public/channels/slack/task-card.js`, all eleven. `authorization.required` gets eve's private
123
+ // delivery surface as its channel, which still carries the session's `state`.
124
+ const RECORDING_EVENTS = [
125
+ "authorization.required",
126
+ "actions.requested",
127
+ "action.result",
128
+ "task.started",
129
+ "task.settled",
130
+ "input.requested",
131
+ "input.resolved",
132
+ "authorization.completed",
133
+ "turn.completed",
134
+ "turn.failed",
135
+ "turn.cancelled",
136
+ ];
137
+ function recordingEvents() {
138
+ const events = {};
139
+ for (const name of RECORDING_EVENTS) {
140
+ events[name] = async (_data, channel, ctx, next) => {
141
+ recordTaskCardRoom(channel, ctx);
142
+ await next();
143
+ };
144
+ }
145
+ return events;
146
+ }
147
+ /**
148
+ * The renderer link. Put it FIRST in the chain, so its handlers record the room before any later
149
+ * link, which may not call `next`, ends the chain. Each handler records and then calls `next`, so it
150
+ * changes no rendering of its own.
151
+ */
152
+ export const taskCardConfidentiality = {
153
+ events: recordingEvents(),
154
+ taskCard: (view, next) => confidentialTaskCard(view, next),
155
+ };
156
+ //# sourceMappingURL=slack-task-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-task-card.js","sourceRoot":"","sources":["../../../agent/channels/slack-task-card.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAQL,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AA4K7B;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5G;AA+QD;mDACmD;AACnD,KAAK,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC;AA4OrH;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,OAAO,EACb,GAAG,GAAE,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,cAAc,CAAuD,GAClH,OAAO,CAAC,cAAc,CAAC,CAYzB"}
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,YAAY,EAGjB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAQL,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AA8K7B;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5G;AA+QD;mDACmD;AACnD,KAAK,cAAc,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC;AA4OrH;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,OAAO,EACb,GAAG,GAAE,CAAC,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,cAAc,CAAuD,GAClH,OAAO,CAAC,cAAc,CAAC,CAYzB"}