@vellumai/assistant 0.10.3-dev.202606252138.db46320 → 0.10.3-dev.202606252237.df0fc92
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/openapi.yaml +24 -0
- package/package.json +1 -1
- package/src/__tests__/list-messages-page-latest.test.ts +9 -0
- package/src/api/responses/conversation-message.ts +9 -0
- package/src/messaging/channel-binding-metadata.ts +1 -1
- package/src/messaging/channel-binding-schema.ts +51 -0
- package/src/messaging/provider-types.ts +0 -8
- package/src/messaging/providers/slack/binding-metadata.ts +7 -5
- package/src/runtime/routes/conversation-list-routes.ts +1 -29
- package/src/runtime/routes/conversation-routes.ts +2 -0
package/openapi.yaml
CHANGED
|
@@ -17426,6 +17426,30 @@ paths:
|
|
|
17426
17426
|
webUrl:
|
|
17427
17427
|
type: string
|
|
17428
17428
|
additionalProperties: false
|
|
17429
|
+
eventKind:
|
|
17430
|
+
type: string
|
|
17431
|
+
enum:
|
|
17432
|
+
- message
|
|
17433
|
+
- reaction
|
|
17434
|
+
reaction:
|
|
17435
|
+
type: object
|
|
17436
|
+
properties:
|
|
17437
|
+
emoji:
|
|
17438
|
+
type: string
|
|
17439
|
+
op:
|
|
17440
|
+
type: string
|
|
17441
|
+
enum:
|
|
17442
|
+
- added
|
|
17443
|
+
- removed
|
|
17444
|
+
actorDisplayName:
|
|
17445
|
+
type: string
|
|
17446
|
+
targetChannelTs:
|
|
17447
|
+
type: string
|
|
17448
|
+
required:
|
|
17449
|
+
- emoji
|
|
17450
|
+
- op
|
|
17451
|
+
- targetChannelTs
|
|
17452
|
+
additionalProperties: false
|
|
17429
17453
|
required:
|
|
17430
17454
|
- channelId
|
|
17431
17455
|
- channelTs
|
package/package.json
CHANGED
|
@@ -109,6 +109,13 @@ interface MessagePayload {
|
|
|
109
109
|
sender?: { displayName?: string; externalUserId?: string };
|
|
110
110
|
messageLink?: { appUrl?: string; webUrl?: string };
|
|
111
111
|
threadLink?: { appUrl?: string; webUrl?: string };
|
|
112
|
+
eventKind?: "message" | "reaction";
|
|
113
|
+
reaction?: {
|
|
114
|
+
emoji: string;
|
|
115
|
+
op: "added" | "removed";
|
|
116
|
+
actorDisplayName?: string;
|
|
117
|
+
targetChannelTs: string;
|
|
118
|
+
};
|
|
112
119
|
};
|
|
113
120
|
}
|
|
114
121
|
|
|
@@ -482,6 +489,7 @@ describe("handleListMessages page=latest", () => {
|
|
|
482
489
|
webUrl:
|
|
483
490
|
"https://example.slack.com/archives/C123ABCDEF/p1710000000000100",
|
|
484
491
|
},
|
|
492
|
+
eventKind: "message",
|
|
485
493
|
});
|
|
486
494
|
});
|
|
487
495
|
|
|
@@ -527,6 +535,7 @@ describe("handleListMessages page=latest", () => {
|
|
|
527
535
|
webUrl:
|
|
528
536
|
"https://example.slack.com/archives/C123ABCDEF/p1710000000000200",
|
|
529
537
|
},
|
|
538
|
+
eventKind: "message",
|
|
530
539
|
});
|
|
531
540
|
});
|
|
532
541
|
|
|
@@ -283,6 +283,13 @@ const SlackMessageLinkSchema = z.object({
|
|
|
283
283
|
webUrl: z.string().optional(),
|
|
284
284
|
});
|
|
285
285
|
|
|
286
|
+
const SlackReactionSchema = z.object({
|
|
287
|
+
emoji: z.string(),
|
|
288
|
+
op: z.enum(["added", "removed"]),
|
|
289
|
+
actorDisplayName: z.string().optional(),
|
|
290
|
+
targetChannelTs: z.string(),
|
|
291
|
+
});
|
|
292
|
+
|
|
286
293
|
/** Slack provenance for a history row that originated from a Slack channel. */
|
|
287
294
|
export const ConversationSlackMessageSchema = z.object({
|
|
288
295
|
channelId: z.string(),
|
|
@@ -297,6 +304,8 @@ export const ConversationSlackMessageSchema = z.object({
|
|
|
297
304
|
.optional(),
|
|
298
305
|
messageLink: SlackMessageLinkSchema.optional(),
|
|
299
306
|
threadLink: SlackMessageLinkSchema.optional(),
|
|
307
|
+
eventKind: z.enum(["message", "reaction"]).optional(),
|
|
308
|
+
reaction: SlackReactionSchema.optional(),
|
|
300
309
|
});
|
|
301
310
|
export type ConversationSlackMessage = z.infer<
|
|
302
311
|
typeof ConversationSlackMessageSchema
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExternalConversationBinding } from "../memory/external-conversation-store.js";
|
|
2
|
-
import type { ChannelBindingMetadata } from "./
|
|
2
|
+
import type { ChannelBindingMetadata } from "./channel-binding-schema.js";
|
|
3
3
|
import { buildSlackBindingMetadata } from "./providers/slack/binding-metadata.js";
|
|
4
4
|
|
|
5
5
|
type BindingMetadataBuilder = (
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const slackThreadSchema = z.object({
|
|
4
|
+
channelId: z.string(),
|
|
5
|
+
threadTs: z.string(),
|
|
6
|
+
link: z
|
|
7
|
+
.object({
|
|
8
|
+
appUrl: z.string().optional(),
|
|
9
|
+
webUrl: z.string().optional(),
|
|
10
|
+
})
|
|
11
|
+
.optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const slackChannelSchema = z.object({
|
|
15
|
+
channelId: z.string(),
|
|
16
|
+
name: z.string().optional(),
|
|
17
|
+
link: z.object({ webUrl: z.string() }).optional(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wire shape of a serialized conversation channel binding — the single source
|
|
22
|
+
* of truth for this contract.
|
|
23
|
+
*
|
|
24
|
+
* Consumed as a route `responseBody` (which drives `openapi.yaml` generation
|
|
25
|
+
* and, in turn, the web client's generated daemon types), and the server-side
|
|
26
|
+
* builders derive their TypeScript types from it via `z.infer`. The shape is
|
|
27
|
+
* therefore declared exactly once.
|
|
28
|
+
*/
|
|
29
|
+
export const channelBindingSchema = z.object({
|
|
30
|
+
sourceChannel: z.string(),
|
|
31
|
+
externalChatId: z.string(),
|
|
32
|
+
externalChatName: z.string().optional(),
|
|
33
|
+
externalThreadId: z.string().optional(),
|
|
34
|
+
externalUserId: z.string().nullable(),
|
|
35
|
+
displayName: z.string().nullable(),
|
|
36
|
+
username: z.string().nullable(),
|
|
37
|
+
slackThread: slackThreadSchema.optional(),
|
|
38
|
+
slackChannel: slackChannelSchema.optional(),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
type ChannelBinding = z.infer<typeof channelBindingSchema>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The channel-specific fields a per-channel builder contributes to a binding
|
|
45
|
+
* (everything beyond the channel-neutral base). Picked from the schema above
|
|
46
|
+
* so a builder's output can never drift from the wire contract.
|
|
47
|
+
*/
|
|
48
|
+
export type ChannelBindingMetadata = Pick<
|
|
49
|
+
ChannelBinding,
|
|
50
|
+
"externalChatName" | "slackThread" | "slackChannel"
|
|
51
|
+
>;
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
/** Platform-agnostic types for the messaging provider abstraction. */
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Extra, channel-specific fields a channel contributes to a serialized
|
|
5
|
-
* conversation channel binding (e.g. deep links back to the source message).
|
|
6
|
-
* Additive by design: each channel returns its own fields, so this is an open
|
|
7
|
-
* record rather than a committed cross-channel schema.
|
|
8
|
-
*/
|
|
9
|
-
export type ChannelBindingMetadata = Record<string, unknown>;
|
|
10
|
-
|
|
11
3
|
export interface Conversation {
|
|
12
4
|
id: string;
|
|
13
5
|
name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getConfig } from "../../../config/loader.js";
|
|
2
2
|
import type { ExternalConversationBinding } from "../../../memory/external-conversation-store.js";
|
|
3
|
-
import type { ChannelBindingMetadata } from "../../
|
|
3
|
+
import type { ChannelBindingMetadata } from "../../channel-binding-schema.js";
|
|
4
4
|
import {
|
|
5
5
|
buildSlackMessageDeepLinks,
|
|
6
6
|
buildSlackWebChannelUrl,
|
|
@@ -12,10 +12,12 @@ import {
|
|
|
12
12
|
* links that jump back to the source thread and channel in the Slack app or
|
|
13
13
|
* web client.
|
|
14
14
|
*
|
|
15
|
-
* The
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* The return type is derived from the channel-binding Zod schema
|
|
16
|
+
* (`ChannelBindingMetadata`) — the single source of truth that also drives
|
|
17
|
+
* `openapi.yaml` and the web client's generated types — so this builder cannot
|
|
18
|
+
* drift from the wire contract. Slack is the only channel that can currently
|
|
19
|
+
* produce message-level deep links, because the link inputs (workspace team
|
|
20
|
+
* id/url + a stable per-message timestamp) only exist for Slack.
|
|
19
21
|
*/
|
|
20
22
|
export function buildSlackBindingMetadata(
|
|
21
23
|
binding: ExternalConversationBinding,
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
import type { ConversationType } from "../../memory/conversation-types.js";
|
|
32
32
|
import { getBindingsForConversations } from "../../memory/external-conversation-store.js";
|
|
33
33
|
import { listGroups } from "../../memory/group-crud.js";
|
|
34
|
+
import { channelBindingSchema } from "../../messaging/channel-binding-schema.js";
|
|
34
35
|
import { UserError } from "../../util/errors.js";
|
|
35
36
|
import { getLogger } from "../../util/logger.js";
|
|
36
37
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
@@ -86,35 +87,6 @@ const assistantAttentionSchema = z.object({
|
|
|
86
87
|
.optional(),
|
|
87
88
|
});
|
|
88
89
|
|
|
89
|
-
const slackThreadSchema = z.object({
|
|
90
|
-
channelId: z.string(),
|
|
91
|
-
threadTs: z.string(),
|
|
92
|
-
link: z
|
|
93
|
-
.object({
|
|
94
|
-
appUrl: z.string().optional(),
|
|
95
|
-
webUrl: z.string().optional(),
|
|
96
|
-
})
|
|
97
|
-
.optional(),
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const slackChannelSchema = z.object({
|
|
101
|
-
channelId: z.string(),
|
|
102
|
-
name: z.string().optional(),
|
|
103
|
-
link: z.object({ webUrl: z.string() }).optional(),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const channelBindingSchema = z.object({
|
|
107
|
-
sourceChannel: z.string(),
|
|
108
|
-
externalChatId: z.string(),
|
|
109
|
-
externalChatName: z.string().optional(),
|
|
110
|
-
externalThreadId: z.string().optional(),
|
|
111
|
-
externalUserId: z.string().nullable(),
|
|
112
|
-
displayName: z.string().nullable(),
|
|
113
|
-
username: z.string().nullable(),
|
|
114
|
-
slackThread: slackThreadSchema.optional(),
|
|
115
|
-
slackChannel: slackChannelSchema.optional(),
|
|
116
|
-
});
|
|
117
|
-
|
|
118
90
|
const forkParentSchema = z.object({
|
|
119
91
|
conversationId: z.string(),
|
|
120
92
|
messageId: z.string(),
|
|
@@ -394,6 +394,8 @@ function buildSlackHistoryMessage(
|
|
|
394
394
|
: {}),
|
|
395
395
|
...(messageLink ? { messageLink } : {}),
|
|
396
396
|
...(threadLink ? { threadLink } : {}),
|
|
397
|
+
...(slackMeta.eventKind ? { eventKind: slackMeta.eventKind } : {}),
|
|
398
|
+
...(slackMeta.reaction ? { reaction: slackMeta.reaction } : {}),
|
|
397
399
|
};
|
|
398
400
|
}
|
|
399
401
|
|