@neta-art/cohub-protocol 1.2.2 → 1.2.3

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.
@@ -1,6 +1,272 @@
1
+ import { z } from "zod";
1
2
  import type { ContentBlock } from "../core/content.js";
2
3
  import type { MessageRecord } from "../model/session.js";
3
4
  export type ChannelProvider = "web" | "websocket" | "discord" | "feishu" | "telegram" | "slack";
5
+ export declare const GATEWAY_CHANNEL_COMMAND_SPECS: readonly [{
6
+ readonly name: "new";
7
+ readonly slash: "/new";
8
+ readonly description: "Start a new Cohub session for this conversation.";
9
+ }, {
10
+ readonly name: "status";
11
+ readonly slash: "/status";
12
+ readonly description: "Show the current Cohub session status.";
13
+ }];
14
+ export type GatewayChannelCommandName = typeof GATEWAY_CHANNEL_COMMAND_SPECS[number]["name"];
15
+ export interface GatewayChannelCommand {
16
+ name: GatewayChannelCommandName;
17
+ rawText?: string;
18
+ args?: string;
19
+ }
20
+ export type GatewayInboundBinding = {
21
+ key: string;
22
+ parentKey?: string | null;
23
+ };
24
+ export declare const gatewayChannelCommandNameSchema: z.ZodEnum<{
25
+ status: "status";
26
+ new: "new";
27
+ }>;
28
+ export declare const gatewayChannelCommandSchema: z.ZodObject<{
29
+ name: z.ZodEnum<{
30
+ status: "status";
31
+ new: "new";
32
+ }>;
33
+ rawText: z.ZodOptional<z.ZodString>;
34
+ args: z.ZodOptional<z.ZodString>;
35
+ }, z.core.$strip>;
36
+ export declare const gatewayMessageCreateEventSchema: z.ZodObject<{
37
+ eventId: z.ZodString;
38
+ timestamp: z.ZodNumber;
39
+ channelId: z.ZodString;
40
+ provider: z.ZodEnum<{
41
+ web: "web";
42
+ websocket: "websocket";
43
+ discord: "discord";
44
+ feishu: "feishu";
45
+ telegram: "telegram";
46
+ slack: "slack";
47
+ }>;
48
+ externalChatId: z.ZodString;
49
+ externalMessageId: z.ZodString;
50
+ bindingKey: z.ZodOptional<z.ZodString>;
51
+ binding: z.ZodOptional<z.ZodObject<{
52
+ key: z.ZodString;
53
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
54
+ }, z.core.$strip>>;
55
+ conversation: z.ZodObject<{
56
+ id: z.ZodString;
57
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
58
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
59
+ }, z.core.$strip>;
60
+ message: z.ZodOptional<z.ZodObject<{
61
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
62
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
63
+ }, z.core.$strip>>;
64
+ sender: z.ZodObject<{
65
+ id: z.ZodString;
66
+ name: z.ZodOptional<z.ZodString>;
67
+ }, z.core.$strip>;
68
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
69
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
70
+ eventType: z.ZodLiteral<"message_create">;
71
+ command: z.ZodOptional<z.ZodNever>;
72
+ }, z.core.$loose>;
73
+ export declare const gatewayConversationCreateEventSchema: z.ZodObject<{
74
+ eventId: z.ZodString;
75
+ timestamp: z.ZodNumber;
76
+ channelId: z.ZodString;
77
+ provider: z.ZodEnum<{
78
+ web: "web";
79
+ websocket: "websocket";
80
+ discord: "discord";
81
+ feishu: "feishu";
82
+ telegram: "telegram";
83
+ slack: "slack";
84
+ }>;
85
+ externalChatId: z.ZodString;
86
+ externalMessageId: z.ZodString;
87
+ bindingKey: z.ZodOptional<z.ZodString>;
88
+ binding: z.ZodOptional<z.ZodObject<{
89
+ key: z.ZodString;
90
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
91
+ }, z.core.$strip>>;
92
+ conversation: z.ZodObject<{
93
+ id: z.ZodString;
94
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
95
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
96
+ }, z.core.$strip>;
97
+ message: z.ZodOptional<z.ZodObject<{
98
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
99
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
100
+ }, z.core.$strip>>;
101
+ sender: z.ZodObject<{
102
+ id: z.ZodString;
103
+ name: z.ZodOptional<z.ZodString>;
104
+ }, z.core.$strip>;
105
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
106
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
107
+ eventType: z.ZodLiteral<"conversation_create">;
108
+ command: z.ZodOptional<z.ZodNever>;
109
+ }, z.core.$loose>;
110
+ export declare const gatewayChannelCommandEventSchema: z.ZodObject<{
111
+ eventId: z.ZodString;
112
+ timestamp: z.ZodNumber;
113
+ channelId: z.ZodString;
114
+ provider: z.ZodEnum<{
115
+ web: "web";
116
+ websocket: "websocket";
117
+ discord: "discord";
118
+ feishu: "feishu";
119
+ telegram: "telegram";
120
+ slack: "slack";
121
+ }>;
122
+ externalChatId: z.ZodString;
123
+ externalMessageId: z.ZodString;
124
+ bindingKey: z.ZodOptional<z.ZodString>;
125
+ binding: z.ZodOptional<z.ZodObject<{
126
+ key: z.ZodString;
127
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
128
+ }, z.core.$strip>>;
129
+ conversation: z.ZodObject<{
130
+ id: z.ZodString;
131
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
132
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
133
+ }, z.core.$strip>;
134
+ message: z.ZodOptional<z.ZodObject<{
135
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
136
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
137
+ }, z.core.$strip>>;
138
+ sender: z.ZodObject<{
139
+ id: z.ZodString;
140
+ name: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strip>;
142
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
143
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
144
+ eventType: z.ZodLiteral<"channel_command">;
145
+ command: z.ZodObject<{
146
+ name: z.ZodEnum<{
147
+ status: "status";
148
+ new: "new";
149
+ }>;
150
+ rawText: z.ZodOptional<z.ZodString>;
151
+ args: z.ZodOptional<z.ZodString>;
152
+ }, z.core.$strip>;
153
+ }, z.core.$loose>;
154
+ export declare const gatewayInboundEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
155
+ eventId: z.ZodString;
156
+ timestamp: z.ZodNumber;
157
+ channelId: z.ZodString;
158
+ provider: z.ZodEnum<{
159
+ web: "web";
160
+ websocket: "websocket";
161
+ discord: "discord";
162
+ feishu: "feishu";
163
+ telegram: "telegram";
164
+ slack: "slack";
165
+ }>;
166
+ externalChatId: z.ZodString;
167
+ externalMessageId: z.ZodString;
168
+ bindingKey: z.ZodOptional<z.ZodString>;
169
+ binding: z.ZodOptional<z.ZodObject<{
170
+ key: z.ZodString;
171
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
172
+ }, z.core.$strip>>;
173
+ conversation: z.ZodObject<{
174
+ id: z.ZodString;
175
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
176
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
177
+ }, z.core.$strip>;
178
+ message: z.ZodOptional<z.ZodObject<{
179
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
180
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
181
+ }, z.core.$strip>>;
182
+ sender: z.ZodObject<{
183
+ id: z.ZodString;
184
+ name: z.ZodOptional<z.ZodString>;
185
+ }, z.core.$strip>;
186
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
187
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
188
+ eventType: z.ZodLiteral<"message_create">;
189
+ command: z.ZodOptional<z.ZodNever>;
190
+ }, z.core.$loose>, z.ZodObject<{
191
+ eventId: z.ZodString;
192
+ timestamp: z.ZodNumber;
193
+ channelId: z.ZodString;
194
+ provider: z.ZodEnum<{
195
+ web: "web";
196
+ websocket: "websocket";
197
+ discord: "discord";
198
+ feishu: "feishu";
199
+ telegram: "telegram";
200
+ slack: "slack";
201
+ }>;
202
+ externalChatId: z.ZodString;
203
+ externalMessageId: z.ZodString;
204
+ bindingKey: z.ZodOptional<z.ZodString>;
205
+ binding: z.ZodOptional<z.ZodObject<{
206
+ key: z.ZodString;
207
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
208
+ }, z.core.$strip>>;
209
+ conversation: z.ZodObject<{
210
+ id: z.ZodString;
211
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
212
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
213
+ }, z.core.$strip>;
214
+ message: z.ZodOptional<z.ZodObject<{
215
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
216
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
217
+ }, z.core.$strip>>;
218
+ sender: z.ZodObject<{
219
+ id: z.ZodString;
220
+ name: z.ZodOptional<z.ZodString>;
221
+ }, z.core.$strip>;
222
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
223
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
224
+ eventType: z.ZodLiteral<"conversation_create">;
225
+ command: z.ZodOptional<z.ZodNever>;
226
+ }, z.core.$loose>, z.ZodObject<{
227
+ eventId: z.ZodString;
228
+ timestamp: z.ZodNumber;
229
+ channelId: z.ZodString;
230
+ provider: z.ZodEnum<{
231
+ web: "web";
232
+ websocket: "websocket";
233
+ discord: "discord";
234
+ feishu: "feishu";
235
+ telegram: "telegram";
236
+ slack: "slack";
237
+ }>;
238
+ externalChatId: z.ZodString;
239
+ externalMessageId: z.ZodString;
240
+ bindingKey: z.ZodOptional<z.ZodString>;
241
+ binding: z.ZodOptional<z.ZodObject<{
242
+ key: z.ZodString;
243
+ parentKey: z.ZodOptional<z.ZodNullable<z.ZodString>>;
244
+ }, z.core.$strip>>;
245
+ conversation: z.ZodObject<{
246
+ id: z.ZodString;
247
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
248
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
249
+ }, z.core.$strip>;
250
+ message: z.ZodOptional<z.ZodObject<{
251
+ parentMessageId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
252
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
253
+ }, z.core.$strip>>;
254
+ sender: z.ZodObject<{
255
+ id: z.ZodString;
256
+ name: z.ZodOptional<z.ZodString>;
257
+ }, z.core.$strip>;
258
+ content: z.ZodArray<z.ZodType<ContentBlock, unknown, z.core.$ZodTypeInternals<ContentBlock, unknown>>>;
259
+ meta: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
260
+ eventType: z.ZodLiteral<"channel_command">;
261
+ command: z.ZodObject<{
262
+ name: z.ZodEnum<{
263
+ status: "status";
264
+ new: "new";
265
+ }>;
266
+ rawText: z.ZodOptional<z.ZodString>;
267
+ args: z.ZodOptional<z.ZodString>;
268
+ }, z.core.$strip>;
269
+ }, z.core.$loose>], "eventType">;
4
270
  export interface DiscordChannelConfig {
5
271
  inbound?: {
6
272
  requireMentionInGuild?: boolean;
@@ -22,15 +288,15 @@ export interface FeishuChannelConfig {
22
288
  };
23
289
  }
24
290
  export type ChannelConfig = DiscordChannelConfig | FeishuChannelConfig | Record<string, unknown>;
25
- export interface GatewayInboundEvent {
291
+ export interface GatewayInboundEventBase {
26
292
  eventId: string;
27
293
  timestamp: number;
28
- eventType?: "message_create" | "conversation_create";
29
294
  channelId: string;
30
295
  provider: ChannelProvider;
31
296
  externalChatId: string;
32
297
  externalMessageId: string;
33
298
  bindingKey?: string;
299
+ binding?: GatewayInboundBinding;
34
300
  conversation: {
35
301
  id: string;
36
302
  parentId?: string | null;
@@ -47,6 +313,19 @@ export interface GatewayInboundEvent {
47
313
  content: ContentBlock[];
48
314
  meta?: Record<string, unknown> | null;
49
315
  }
316
+ export interface GatewayMessageCreateEvent extends GatewayInboundEventBase {
317
+ eventType: "message_create";
318
+ command?: never;
319
+ }
320
+ export interface GatewayConversationCreateEvent extends GatewayInboundEventBase {
321
+ eventType: "conversation_create";
322
+ command?: never;
323
+ }
324
+ export interface GatewayChannelCommandEvent extends GatewayInboundEventBase {
325
+ eventType: "channel_command";
326
+ command: GatewayChannelCommand;
327
+ }
328
+ export type GatewayInboundEvent = GatewayMessageCreateEvent | GatewayConversationCreateEvent | GatewayChannelCommandEvent;
50
329
  export interface GatewaySessionOutputBase {
51
330
  type: "session.turn.patch" | "session.turn.error" | "session.message.persisted";
52
331
  spaceId: string;
@@ -80,6 +359,7 @@ export interface GatewaySessionTurnPatchOutput extends GatewaySessionOutputBase
80
359
  type: "session.turn.patch";
81
360
  turnId: string | null;
82
361
  messageId: string | null;
362
+ messageOrdinal?: number | null;
83
363
  anchorUserMessageId: string | null;
84
364
  seq: number;
85
365
  baseSeq: number;
@@ -1 +1,113 @@
1
- export {};
1
+ import { z } from "zod";
2
+ export const GATEWAY_CHANNEL_COMMAND_SPECS = [
3
+ {
4
+ name: "new",
5
+ slash: "/new",
6
+ description: "Start a new Cohub session for this conversation.",
7
+ },
8
+ {
9
+ name: "status",
10
+ slash: "/status",
11
+ description: "Show the current Cohub session status.",
12
+ },
13
+ ];
14
+ const GATEWAY_CHANNEL_COMMAND_NAMES = GATEWAY_CHANNEL_COMMAND_SPECS.map((spec) => spec.name);
15
+ const recordSchema = z.record(z.string(), z.unknown());
16
+ const contentBlockMetaSchema = recordSchema;
17
+ const contentBlockSchema = z.lazy(() => z.discriminatedUnion("type", [
18
+ z.object({
19
+ type: z.literal("text"),
20
+ text: z.string(),
21
+ _meta: contentBlockMetaSchema.optional(),
22
+ }),
23
+ z.object({
24
+ type: z.literal("thinking"),
25
+ thinking: z.string(),
26
+ signature: z.string().optional(),
27
+ _meta: contentBlockMetaSchema.optional(),
28
+ }),
29
+ z.object({
30
+ type: z.literal("image"),
31
+ source: z.union([
32
+ z.object({ type: z.literal("url"), url: z.string() }),
33
+ z.object({ type: z.literal("base64"), media_type: z.string(), data: z.string() }),
34
+ ]),
35
+ _meta: contentBlockMetaSchema.optional(),
36
+ }),
37
+ z.object({
38
+ type: z.literal("tool_use"),
39
+ id: z.string(),
40
+ name: z.string(),
41
+ input: recordSchema,
42
+ _meta: contentBlockMetaSchema.optional(),
43
+ }),
44
+ z.object({
45
+ type: z.literal("tool_result"),
46
+ tool_use_id: z.string(),
47
+ content: z.union([z.string(), z.array(contentBlockSchema)]),
48
+ is_error: z.boolean().optional(),
49
+ _meta: contentBlockMetaSchema.optional(),
50
+ }),
51
+ z.object({
52
+ type: z.literal("system_note"),
53
+ note_type: z.enum(["session_created", "forked", "compacted", "info"]),
54
+ text: z.string(),
55
+ _meta: contentBlockMetaSchema.optional(),
56
+ }),
57
+ ]));
58
+ export const gatewayChannelCommandNameSchema = z.enum(GATEWAY_CHANNEL_COMMAND_NAMES);
59
+ export const gatewayChannelCommandSchema = z.object({
60
+ name: gatewayChannelCommandNameSchema,
61
+ rawText: z.string().optional(),
62
+ args: z.string().optional(),
63
+ });
64
+ const channelProviderSchema = z.enum(["web", "websocket", "discord", "feishu", "telegram", "slack"]);
65
+ const gatewayInboundBindingSchema = z.object({
66
+ key: z.string().min(1),
67
+ parentKey: z.string().min(1).nullable().optional(),
68
+ });
69
+ const gatewayInboundConversationSchema = z.object({
70
+ id: z.string(),
71
+ parentId: z.string().nullable().optional(),
72
+ meta: recordSchema.nullable().optional(),
73
+ });
74
+ const gatewayInboundMessageSchema = z.object({
75
+ parentMessageId: z.string().nullable().optional(),
76
+ meta: recordSchema.nullable().optional(),
77
+ });
78
+ const gatewayInboundSenderSchema = z.object({
79
+ id: z.string(),
80
+ name: z.string().optional(),
81
+ });
82
+ const gatewayInboundEventBaseSchema = z.object({
83
+ eventId: z.string(),
84
+ timestamp: z.number(),
85
+ channelId: z.string(),
86
+ provider: channelProviderSchema,
87
+ externalChatId: z.string(),
88
+ externalMessageId: z.string(),
89
+ bindingKey: z.string().optional(),
90
+ binding: gatewayInboundBindingSchema.optional(),
91
+ conversation: gatewayInboundConversationSchema,
92
+ message: gatewayInboundMessageSchema.optional(),
93
+ sender: gatewayInboundSenderSchema,
94
+ content: z.array(contentBlockSchema),
95
+ meta: recordSchema.nullable().optional(),
96
+ });
97
+ export const gatewayMessageCreateEventSchema = gatewayInboundEventBaseSchema.extend({
98
+ eventType: z.literal("message_create"),
99
+ command: z.never().optional(),
100
+ }).passthrough();
101
+ export const gatewayConversationCreateEventSchema = gatewayInboundEventBaseSchema.extend({
102
+ eventType: z.literal("conversation_create"),
103
+ command: z.never().optional(),
104
+ }).passthrough();
105
+ export const gatewayChannelCommandEventSchema = gatewayInboundEventBaseSchema.extend({
106
+ eventType: z.literal("channel_command"),
107
+ command: gatewayChannelCommandSchema,
108
+ }).passthrough();
109
+ export const gatewayInboundEventSchema = z.discriminatedUnion("eventType", [
110
+ gatewayMessageCreateEventSchema,
111
+ gatewayConversationCreateEventSchema,
112
+ gatewayChannelCommandEventSchema,
113
+ ]);
@@ -0,0 +1,136 @@
1
+ export type ChannelProvider = "web" | "websocket" | "discord" | "feishu" | "telegram" | "slack";
2
+ export declare function buildSessionSourceChannel(event: GatewayInboundEvent): string;
3
+ export interface DiscordChannelConfig {
4
+ inbound?: {
5
+ requireMentionInGuild?: boolean;
6
+ };
7
+ outbound?: {
8
+ showThinking?: boolean;
9
+ showToolCalls?: boolean;
10
+ };
11
+ }
12
+ export type ChannelConfig = DiscordChannelConfig | FeishuChannelConfig | Record<string, unknown>;
13
+ export interface FeishuChannelConfig {
14
+ brand?: "feishu" | "lark";
15
+ inbound?: {
16
+ requireMentionInGroup?: boolean;
17
+ };
18
+ outbound?: {
19
+ renderMode?: "card" | "post";
20
+ showThinking?: boolean;
21
+ showToolCalls?: boolean;
22
+ };
23
+ }
24
+ export interface GatewayInboundEvent {
25
+ eventId: string;
26
+ timestamp: number;
27
+ eventType?: "message_create" | "conversation_create";
28
+ channelId: string;
29
+ provider: ChannelProvider;
30
+ externalChatId: string;
31
+ externalMessageId: string;
32
+ bindingKey?: string;
33
+ conversation: {
34
+ id: string;
35
+ parentId?: string | null;
36
+ meta?: Record<string, unknown> | null;
37
+ };
38
+ message?: {
39
+ parentMessageId?: string | null;
40
+ meta?: Record<string, unknown> | null;
41
+ };
42
+ sender: {
43
+ id: string;
44
+ name?: string;
45
+ };
46
+ content: import("./session-ingestion.js").ContentBlock[];
47
+ meta?: Record<string, unknown> | null;
48
+ }
49
+ export interface GatewaySessionOutputBase {
50
+ type: "session.turn.progress" | "session.turn.final" | "session.turn.error" | "session.message.persisted";
51
+ spaceId: string;
52
+ sessionId: string;
53
+ }
54
+ export interface GatewaySessionTurnProgressOutput extends GatewaySessionOutputBase {
55
+ type: "session.turn.progress";
56
+ anchorUserMessageId: string | null;
57
+ content: import("./session-ingestion.js").ContentBlock[];
58
+ }
59
+ export interface GatewaySessionTurnFinalOutput extends GatewaySessionOutputBase {
60
+ type: "session.turn.final";
61
+ sessionMessageId: string | null;
62
+ anchorUserMessageId: string | null;
63
+ content: import("./session-ingestion.js").ContentBlock[];
64
+ }
65
+ export interface GatewaySessionTurnErrorOutput extends GatewaySessionOutputBase {
66
+ type: "session.turn.error";
67
+ anchorUserMessageId: string | null;
68
+ error: string;
69
+ }
70
+ export interface GatewaySessionMessagePersistedOutput extends GatewaySessionOutputBase {
71
+ type: "session.message.persisted";
72
+ message: import("./session-ingestion.js").MessageRecord;
73
+ }
74
+ export type GatewaySessionOutput = GatewaySessionTurnProgressOutput | GatewaySessionTurnFinalOutput | GatewaySessionTurnErrorOutput | GatewaySessionMessagePersistedOutput;
75
+ export interface DiscordDeliveryPlan {
76
+ adapter: "discord";
77
+ mode: "send" | "upsert";
78
+ primaryText: string;
79
+ continuationChunks: string[];
80
+ files: string[];
81
+ replyToExternalMessageId?: string;
82
+ turnAnchorMessageId?: string | null;
83
+ preferredEditExternalMessageId?: string | null;
84
+ }
85
+ export interface FeishuDeliveryPlan {
86
+ adapter: "feishu";
87
+ mode: "create_or_update";
88
+ renderMode: "card" | "post";
89
+ msgType: "interactive" | "post";
90
+ content: string;
91
+ imageKeys: string[];
92
+ replyToExternalMessageId?: string;
93
+ turnAnchorMessageId?: string | null;
94
+ preferredEditExternalMessageId?: string | null;
95
+ }
96
+ export type GatewayDeliveryPlan = DiscordDeliveryPlan | FeishuDeliveryPlan;
97
+ export interface GatewayOutboundCommand {
98
+ commandId: string;
99
+ timestamp: number;
100
+ channelId: string;
101
+ provider: ChannelProvider;
102
+ externalChatId: string;
103
+ content: import("./session-ingestion.js").ContentBlock[];
104
+ replyToExternalMessageId?: string;
105
+ spaceId?: string;
106
+ spaceSessionId?: string;
107
+ sessionMessageId?: string;
108
+ deliveryPlan?: GatewayDeliveryPlan | null;
109
+ meta?: (Record<string, unknown> & {
110
+ sessionOutput?: GatewaySessionOutput | null;
111
+ }) | null;
112
+ }
113
+ export interface GatewayControlCommand {
114
+ action: "connect" | "disconnect" | "reload";
115
+ configs: {
116
+ channelId: string;
117
+ provider: ChannelProvider;
118
+ credentials: Record<string, unknown>;
119
+ }[];
120
+ }
121
+ export type GatewayLogDirection = "inbound" | "outbound";
122
+ export type GatewayLogStatus = "pending" | "success" | "failed";
123
+ export interface GatewayLogEvent {
124
+ logId: string;
125
+ timestamp: number;
126
+ direction: GatewayLogDirection;
127
+ provider: ChannelProvider;
128
+ channelId: string;
129
+ externalChatId: string;
130
+ externalMessageId?: string;
131
+ rawPayload: Record<string, unknown>;
132
+ normalizedPayload?: Record<string, unknown>;
133
+ status: GatewayLogStatus;
134
+ errorMessage?: string;
135
+ correlationId?: string;
136
+ }
@@ -0,0 +1,48 @@
1
+ export function buildSessionSourceChannel(event) {
2
+ const provider = event.provider;
3
+ const meta = (event.conversation?.meta ?? event.meta ?? {});
4
+ switch (provider) {
5
+ case "discord":
6
+ return buildDiscordSourceChannel(event, meta);
7
+ case "feishu":
8
+ return buildFeishuSourceChannel(event, meta);
9
+ case "web":
10
+ return "web";
11
+ default:
12
+ return `${provider}:${event.conversation?.id?.trim() || event.externalChatId}`;
13
+ }
14
+ }
15
+ function buildDiscordSourceChannel(event, meta) {
16
+ const isDm = meta.isDm === true;
17
+ const guildName = typeof meta.guildName === "string" ? meta.guildName : null;
18
+ const channelName = typeof meta.channelName === "string" ? meta.channelName : null;
19
+ const parentChannelName = typeof meta.parentChannelName === "string" ? meta.parentChannelName : null;
20
+ const threadName = typeof meta.threadName === "string" ? meta.threadName : null;
21
+ const senderName = event.sender?.name ?? null;
22
+ if (isDm) {
23
+ return `discord:dm:${senderName ?? event.sender.id}`;
24
+ }
25
+ if (threadName && parentChannelName && guildName) {
26
+ return `discord:${guildName}:#${parentChannelName}>${threadName}`;
27
+ }
28
+ if (channelName && guildName) {
29
+ return `discord:${guildName}:#${channelName}`;
30
+ }
31
+ if (guildName) {
32
+ return `discord:${guildName}`;
33
+ }
34
+ return `discord:${event.conversation?.id?.trim() || event.externalChatId}`;
35
+ }
36
+ function buildFeishuSourceChannel(event, meta) {
37
+ const chatType = meta.chatType;
38
+ const chatName = typeof meta.chatName === "string" ? meta.chatName : null;
39
+ const senderName = event.sender?.name ?? null;
40
+ const isDm = chatType === "p2p";
41
+ if (isDm) {
42
+ return `feishu:dm:${senderName ?? event.sender.id}`;
43
+ }
44
+ if (chatName) {
45
+ return `feishu:group:${chatName}`;
46
+ }
47
+ return `feishu:${event.conversation?.id?.trim() || event.externalChatId}`;
48
+ }
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from "./realtime/websocket.js";
7
7
  export * from "./gateway/index.js";
8
8
  export * from "./task/index.js";
9
9
  export * from "./fs/index.js";
10
+ export * from "./ports/index.js";
package/dist/index.js CHANGED
@@ -7,3 +7,4 @@ export * from "./realtime/websocket.js";
7
7
  export * from "./gateway/index.js";
8
8
  export * from "./task/index.js";
9
9
  export * from "./fs/index.js";
10
+ export * from "./ports/index.js";
@@ -1,6 +1,6 @@
1
1
  import type { ContentBlock } from "../core/content.js";
2
2
  import type { Usage } from "../core/usage.js";
3
- export type { MessageToolCallsFile, SessionTurnIntent, SessionTurnIntermediateIndex, SessionTurnIntermediateSummary, SessionTurnRecord, SessionTurnStatus, SessionTurnSummary, StoredIntermediateMessage, StoredIntermediateMessageToolCallSummary, StoredToolCall, TurnIntermediateMessagesFile, } from "./turn.js";
3
+ export type { MessageToolCallsFile, SessionTurnIntent, SessionTurnIntermediateIndex, SessionTurnIntermediateSummary, SessionTurnIndexItem, SessionTurnRecord, SessionTurnStatus, SessionTurnSummary, StoredIntermediateMessage, StoredToolCall, TurnIntermediateMessagesFile, } from "./turn.js";
4
4
  export type SessionPromptInput = {
5
5
  spaceId: string;
6
6
  sessionId: string;