Skip to content

Commit c746621

Browse files
committed
feat(webhooks): channel reactions/startOn, session-target deliveries, and a data-plane DB seam
Bundles the uncommitted webhook work (entangled across shared files, so committed together): - Channels: a startOn session-start gate (only summon a new session on matching events, otherwise resume), agent and lifecycle reactions, Slack mrkdwn conversion, and a mentions() helper in @trigger.dev/slack. - Deliveries UI links the chat.agent session as the delivery target. - Webhook database seam: an injected webhookPrisma (writer) and webhookReplica (reader) so the whole webhook feature (WebhookEndpoint + WebhookDelivery) can move to a dedicated Postgres by config. Prep only and connection-neutral until WEBHOOK_DATABASE_URL is set; narrow WebhookDatabase types keep control-plane tables off the webhook client, with a two-DB test as the runtime backstop.
1 parent 3a39054 commit c746621

36 files changed

Lines changed: 910 additions & 318 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
"@trigger.dev/core": patch
3+
"@trigger.dev/sdk": patch
4+
"@trigger.dev/slack": patch
5+
"trigger.dev": patch
6+
---
7+
8+
More control over `chat.agent` channels. A channel can now gate when a *new* session starts with `startOn`, so an agent only engages on the events you choose (e.g. a Slack mention) and otherwise just continues the existing thread. The `@trigger.dev/slack` package adds a `mentions()` helper for the mention predicate, converts the agent's markdown reply into Slack mrkdwn, and only routes real user messages (system messages like channel joins no longer trigger a turn).
9+
10+
Agents can also react to the triggering message. Lifecycle reactions signal turn state (one while working, swapped to done, or error on failure), and the agent can react itself from `run()`:
11+
12+
```ts
13+
import { slack, mentions } from "@trigger.dev/slack";
14+
15+
slack({
16+
id: "support",
17+
token: process.env.SLACK_BOT_TOKEN,
18+
startOn: mentions("U012BOT"),
19+
reactions: { working: ["eyes", "hourglass_flowing_sand"], done: "white_check_mark", error: "x" },
20+
});
21+
```
22+
23+
Each lifecycle reaction is a single emoji, an array (one picked at random per turn), or a function of the event. Inside `run()`, `channel?.react("white_check_mark")` reacts on demand.

apps/webapp/app/components/webhookDeliveries/v1/DeliveriesTable.tsx

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { ArrowRightIcon } from "@heroicons/react/20/solid";
22
import { useLocation, useNavigation } from "@remix-run/react";
3+
import { AIChatIcon } from "~/assets/icons/AIChatIcon";
4+
import { RunsIcon } from "~/assets/icons/RunsIcon";
35
import { WebhookIcon } from "~/assets/icons/WebhookIcon";
46
import { DateTime } from "~/components/primitives/DateTime";
57
import { MiddleTruncate } from "~/components/primitives/MiddleTruncate";
@@ -21,7 +23,12 @@ import { useEnvironment } from "~/hooks/useEnvironment";
2123
import { useOrganization } from "~/hooks/useOrganizations";
2224
import { useProject } from "~/hooks/useProject";
2325
import { type WebhookDeliveryListItem } from "~/presenters/v3/WebhookDetailPresenter.server";
24-
import { v3RunPath, v3WebhookDeliveryPath, v3WebhookTaskPath } from "~/utils/pathBuilder";
26+
import {
27+
v3RunPath,
28+
v3SessionPath,
29+
v3WebhookDeliveryPath,
30+
v3WebhookTaskPath,
31+
} from "~/utils/pathBuilder";
2532
import { cn } from "~/utils/cn";
2633
import { DeliveryStatusBadge } from "./DeliveryStatus";
2734

@@ -61,7 +68,7 @@ export function DeliveriesTable({
6168
<TableHeaderCell>Delivery</TableHeaderCell>
6269
<TableHeaderCell>Status</TableHeaderCell>
6370
<TableHeaderCell>External delivery ID</TableHeaderCell>
64-
<TableHeaderCell>Run</TableHeaderCell>
71+
<TableHeaderCell>Target</TableHeaderCell>
6572
<TableHeaderCell>Created</TableHeaderCell>
6673
<TableHeaderCell>Processed</TableHeaderCell>
6774
<TableHeaderCell>Error</TableHeaderCell>
@@ -89,6 +96,14 @@ export function DeliveriesTable({
8996
})
9097
: undefined;
9198

99+
// Session deliveries route to a session (their run is just its current turn), so the
100+
// session is the meaningful target; task deliveries fall back to the run.
101+
const sessionPath = delivery.session
102+
? v3SessionPath(organization, project, environment, {
103+
friendlyId: delivery.session.friendlyId,
104+
})
105+
: undefined;
106+
92107
const webhookPath = delivery.webhook
93108
? v3WebhookTaskPath(organization, project, environment, delivery.webhook.slug)
94109
: undefined;
@@ -132,9 +147,17 @@ export function DeliveriesTable({
132147
<span className="text-text-dimmed">None</span>
133148
)}
134149
</TableCell>
135-
<TableCell to={runPath}>
136-
{delivery.run ? (
137-
<span className="font-mono text-xs">{delivery.run.friendlyId}</span>
150+
<TableCell to={sessionPath ?? runPath}>
151+
{delivery.session ? (
152+
<span className="flex items-center gap-x-1">
153+
<AIChatIcon className="size-4 text-sessions" />
154+
<span className="font-mono text-xs">{delivery.session.friendlyId}</span>
155+
</span>
156+
) : delivery.run ? (
157+
<span className="flex items-center gap-x-1">
158+
<RunsIcon className="size-4 text-runs" />
159+
<span className="font-mono text-xs">{delivery.run.friendlyId}</span>
160+
</span>
138161
) : (
139162
<span className="text-text-dimmed">None</span>
140163
)}
@@ -163,7 +186,11 @@ export function DeliveriesTable({
163186
<span className="text-text-dimmed">None</span>
164187
)}
165188
</TableCell>
166-
<DeliveryActionsCell deliveryPath={deliveryPath} runPath={runPath} />
189+
<DeliveryActionsCell
190+
deliveryPath={deliveryPath}
191+
runPath={runPath}
192+
sessionPath={sessionPath}
193+
/>
167194
</TableRow>
168195
);
169196
})
@@ -186,9 +213,11 @@ export function DeliveriesTable({
186213
function DeliveryActionsCell({
187214
deliveryPath,
188215
runPath,
216+
sessionPath,
189217
}: {
190218
deliveryPath: string;
191219
runPath?: string;
220+
sessionPath?: string;
192221
}) {
193222
return (
194223
<TableCellMenu
@@ -201,6 +230,14 @@ function DeliveryActionsCell({
201230
leadingIconClassName="text-webhooks"
202231
title="View delivery"
203232
/>
233+
{sessionPath ? (
234+
<PopoverMenuItem
235+
to={sessionPath}
236+
icon={ArrowRightIcon}
237+
leadingIconClassName="text-runs"
238+
title="View session"
239+
/>
240+
) : null}
204241
{runPath ? (
205242
<PopoverMenuItem
206243
to={runPath}

0 commit comments

Comments
 (0)