@neta-art/cohub-protocol 1.2.2 → 1.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.
@@ -54,10 +54,52 @@ export type SpaceFsUploadEntry = {
54
54
  };
55
55
  export type SpaceFsUploadError = {
56
56
  name: string;
57
- code: "file_too_large" | "name_invalid" | "write_failed";
57
+ code: "file_too_large" | "name_invalid" | "path_invalid" | "write_failed" | "object_missing";
58
58
  message: string;
59
59
  };
60
60
  export type SpaceFsUploadResponse = {
61
61
  uploaded: SpaceFsUploadEntry[];
62
62
  errors: SpaceFsUploadError[];
63
63
  };
64
+ export type SpaceFsUploadPlanEntryInput = {
65
+ id: string;
66
+ name: string;
67
+ relativePath: string;
68
+ size: number;
69
+ mimeType?: string | null;
70
+ lastModified?: number;
71
+ };
72
+ export type SpaceFsCreateUploadInput = {
73
+ targetDir?: string;
74
+ entries: SpaceFsUploadPlanEntryInput[];
75
+ };
76
+ export type SpaceFsUploadPlanEntry = {
77
+ id: string;
78
+ objectKey: string;
79
+ uploadUrl: string;
80
+ headers?: Record<string, string>;
81
+ };
82
+ export type SpaceFsCreateUploadResponse = {
83
+ uploadId: string;
84
+ expiresAt: string;
85
+ entries: SpaceFsUploadPlanEntry[];
86
+ };
87
+ export type SpaceFsCompleteUploadInput = {
88
+ entries: Array<{
89
+ id: string;
90
+ etag?: string | null;
91
+ }>;
92
+ };
93
+ export type SpaceFsCompleteUploadResponse = {
94
+ ok: true;
95
+ taskRunId: string;
96
+ };
97
+ export type SpaceFsUploadProgress = {
98
+ phase: "queued" | "importing" | "done" | "failed";
99
+ totalFiles: number;
100
+ importedFiles: number;
101
+ totalBytes: number;
102
+ importedBytes: number;
103
+ currentPath?: string;
104
+ errors: SpaceFsUploadError[];
105
+ };
@@ -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
+ ]);
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;
@@ -84,6 +84,11 @@ export type SessionRecord = {
84
84
  createdAt: string;
85
85
  updatedAt: string;
86
86
  };
87
+ export type MessageAuthorProfile = {
88
+ userUuid: string;
89
+ displayName: string;
90
+ avatarUrl: string | null;
91
+ };
87
92
  export type MessageRecord = {
88
93
  id: string;
89
94
  sessionId: string;
@@ -97,5 +102,7 @@ export type MessageRecord = {
97
102
  errorMessage: string | null;
98
103
  usage: Usage | null;
99
104
  meta: Record<string, unknown> | null;
105
+ authorUuid?: string | null;
106
+ authorProfile?: MessageAuthorProfile | null;
100
107
  createdAt: string;
101
108
  };
@@ -20,12 +20,6 @@ export type SessionTurnIntermediateSummary = {
20
20
  lastMessageText?: string | null;
21
21
  hasError?: boolean;
22
22
  };
23
- export type StoredIntermediateMessageToolCallSummary = {
24
- id: string;
25
- name: string;
26
- status: "running" | "done" | "failed";
27
- input: Record<string, unknown>;
28
- };
29
23
  export type StoredIntermediateMessage = {
30
24
  id: string;
31
25
  sessionId: string;
@@ -37,7 +31,6 @@ export type StoredIntermediateMessage = {
37
31
  stopReason: string | null;
38
32
  errorMessage: string | null;
39
33
  usage: Usage | null;
40
- toolCalls: StoredIntermediateMessageToolCallSummary[];
41
34
  toolCallsObjectKey: string | null;
42
35
  meta: Record<string, unknown> | null;
43
36
  createdAt: string;
@@ -46,11 +39,12 @@ export type StoredToolCall = {
46
39
  id: string;
47
40
  name: string;
48
41
  input: Record<string, unknown>;
42
+ meta: Record<string, unknown> | null;
49
43
  result: {
50
44
  content: string | ContentBlock[] | null;
51
45
  isError: boolean;
46
+ meta: Record<string, unknown> | null;
52
47
  } | null;
53
- meta: Record<string, unknown> | null;
54
48
  };
55
49
  export type MessageToolCallsFile = {
56
50
  version: 1;
@@ -68,6 +62,28 @@ export type TurnIntermediateMessagesFile = {
68
62
  summary: SessionTurnIntermediateSummary;
69
63
  messages: StoredIntermediateMessage[];
70
64
  };
65
+ export type SessionTurnIndexItem = {
66
+ id: string;
67
+ sessionId: string;
68
+ sequence: number;
69
+ status: SessionTurnStatus;
70
+ startedAt: string | null;
71
+ completedAt: string | null;
72
+ createdAt: string;
73
+ updatedAt: string;
74
+ userPreview: string | null;
75
+ assistantPreview: string | null;
76
+ provider: string | null;
77
+ model: string | null;
78
+ finalUsage: Usage | null;
79
+ totalUsage: Usage | null;
80
+ errorMessage: string | null;
81
+ };
82
+ export type SessionTurnAuthorProfile = {
83
+ userUuid: string;
84
+ displayName: string;
85
+ avatarUrl: string | null;
86
+ };
71
87
  export type SessionTurnRecord = {
72
88
  id: string;
73
89
  sessionId: string;
@@ -83,11 +99,13 @@ export type SessionTurnRecord = {
83
99
  model: string | null;
84
100
  stopReason: string | null;
85
101
  errorMessage: string | null;
86
- usage: Usage | null;
102
+ finalUsage: Usage | null;
103
+ totalUsage: Usage | null;
87
104
  summary: SessionTurnSummary | null;
88
105
  intermediateIndex: SessionTurnIntermediateIndex | null;
89
106
  intermediateSummary: SessionTurnIntermediateSummary | null;
90
107
  meta: Record<string, unknown> | null;
108
+ authorProfile?: SessionTurnAuthorProfile | null;
91
109
  startedAt: string | null;
92
110
  completedAt: string | null;
93
111
  createdAt: string;
@@ -0,0 +1,21 @@
1
+ export declare const SANDBOX_PUBLIC_PORTS: readonly [3000, 5173];
2
+ export type SandboxPublicPort = (typeof SANDBOX_PUBLIC_PORTS)[number];
3
+ export type SpacePortStatus = "listening" | "closed";
4
+ export type SpacePortChange = {
5
+ port: SandboxPublicPort | number;
6
+ protocol: "tcp";
7
+ status: SpacePortStatus;
8
+ observedAt: number;
9
+ };
10
+ export type SpacePortsChangedPayload = {
11
+ source: "sandbox-port-watch" | "sandbox-port-watch-started";
12
+ seq?: number;
13
+ resync?: boolean;
14
+ ports: SpacePortChange[];
15
+ };
16
+ export type SpacePublicEndpoint = {
17
+ url: string;
18
+ status?: SpacePortStatus | "unknown";
19
+ observedAt?: number;
20
+ };
21
+ export type SpacePublicEndpoints = Record<string, SpacePublicEndpoint>;
@@ -0,0 +1 @@
1
+ export const SANDBOX_PUBLIC_PORTS = [3000, 5173];
@@ -8,6 +8,8 @@ export type SessionStreamEvent = {
8
8
  baseSeq: number;
9
9
  content: ContentBlock[];
10
10
  snapshotContent?: ContentBlock[];
11
+ messageId?: string | null;
12
+ messageOrdinal?: number | null;
11
13
  sourceMessageId: string | null;
12
14
  timestamp: number;
13
15
  turnEnd?: boolean;
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import type { ContentBlock } from "../core/content.js";
3
- import type { MessageRecord } from "../model/session.js";
3
+ import type { MessageRecord, SessionTurnRecord } from "../model/session.js";
4
4
  import type { SpaceFsChangedPayload } from "../fs/index.js";
5
+ import type { SpacePortsChangedPayload } from "../ports/index.js";
5
6
  export declare const WS_COMPACT_STREAM_CAPABILITY = "session.compact_stream.v1";
6
7
  export declare const contentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
8
  type: z.ZodLiteral<"text">;
@@ -293,6 +294,8 @@ export type SessionTurnProgressEvent = {
293
294
  spaceId: string;
294
295
  sessionId: string;
295
296
  payload: {
297
+ messageId: string | null;
298
+ messageOrdinal?: number | null;
296
299
  anchorUserMessageId: string | null;
297
300
  content: ContentBlock[];
298
301
  };
@@ -321,6 +324,17 @@ export type RealtimePatchOperation = {
321
324
  o?: undefined;
322
325
  p?: undefined;
323
326
  };
327
+ export type RealtimePatchIdentityInput = {
328
+ turnId?: unknown;
329
+ messageId?: unknown;
330
+ sourceMessageId?: unknown;
331
+ anchorUserMessageId?: unknown;
332
+ messageOrdinal?: unknown;
333
+ sessionId?: unknown;
334
+ };
335
+ export declare const getSessionTurnPatchStreamKey: (input: RealtimePatchIdentityInput, options?: {
336
+ includeSessionFallback?: boolean;
337
+ }) => string | null;
324
338
  export type SessionTurnPatchEvent = {
325
339
  id: string;
326
340
  timestamp: number;
@@ -332,12 +346,37 @@ export type SessionTurnPatchEvent = {
332
346
  payload: {
333
347
  turnId: string | null;
334
348
  messageId: string | null;
349
+ messageOrdinal?: number | null;
350
+ sourceMessageId?: string | null;
335
351
  anchorUserMessageId: string | null;
336
352
  seq: number;
337
353
  baseSeq: number;
338
354
  ops: RealtimePatchOperation[];
339
355
  };
340
356
  };
357
+ export type SessionTurnSnapshotMessage = {
358
+ messageId: string | null;
359
+ messageOrdinal: number | null;
360
+ content: ContentBlock[];
361
+ };
362
+ export type SessionTurnSnapshotEvent = {
363
+ id: string;
364
+ timestamp: number;
365
+ domain: "session";
366
+ type: "session.turn.snapshot";
367
+ requestId?: string | null;
368
+ spaceId: string;
369
+ sessionId: string;
370
+ payload: {
371
+ turnId: string | null;
372
+ anchorUserMessageId: string | null;
373
+ seq: number;
374
+ current: SessionTurnSnapshotMessage & {
375
+ appendPath: string | null;
376
+ };
377
+ intermediateMessages: SessionTurnSnapshotMessage[];
378
+ };
379
+ };
341
380
  export type SessionTurnErrorEvent = {
342
381
  id: string;
343
382
  timestamp: number;
@@ -351,6 +390,31 @@ export type SessionTurnErrorEvent = {
351
390
  error: string;
352
391
  };
353
392
  };
393
+ export type RealtimeTurnRecord = Partial<Pick<SessionTurnRecord, "id" | "sessionId" | "sequence" | "status" | "intent" | "userUuid" | "authorProfile" | "userText" | "assistantText" | "provider" | "model" | "stopReason" | "errorMessage" | "finalUsage" | "totalUsage" | "summary" | "intermediateIndex" | "intermediateSummary" | "startedAt" | "completedAt" | "createdAt" | "updatedAt">>;
394
+ export type SessionTurnUpdatedEvent = {
395
+ id: string;
396
+ timestamp: number;
397
+ domain: "session";
398
+ type: "session.turn.updated";
399
+ requestId?: string | null;
400
+ spaceId: string;
401
+ sessionId: string;
402
+ payload: {
403
+ turn: RealtimeTurnRecord;
404
+ };
405
+ };
406
+ export type SessionTurnFinalizedEvent = {
407
+ id: string;
408
+ timestamp: number;
409
+ domain: "session";
410
+ type: "session.turn.finalized";
411
+ requestId?: string | null;
412
+ spaceId: string;
413
+ sessionId: string;
414
+ payload: {
415
+ turn: RealtimeTurnRecord;
416
+ };
417
+ };
354
418
  export type RealtimeMessageRecord = Pick<MessageRecord, "id" | "sessionId" | "role" | "content" | "text" | "sequence" | "provider" | "model" | "stopReason" | "errorMessage" | "usage" | "meta" | "createdAt">;
355
419
  export type SessionMessagePersistedEvent = {
356
420
  id: string;
@@ -374,6 +438,16 @@ export type SpaceFsChangedEvent = {
374
438
  sessionId?: string | null;
375
439
  payload: SpaceFsChangedPayload;
376
440
  };
377
- export type RealtimeServerEvent = SystemReadyEvent | SystemAuthOkEvent | SystemRequestErrorEvent | SystemPongEvent | SystemAckOkEvent | SessionRequestAcceptedEvent | SessionRequestErrorEvent | SessionTurnProgressEvent | SessionTurnPatchEvent | SessionTurnErrorEvent | SessionMessagePersistedEvent | SpaceFsChangedEvent;
441
+ export type SpacePortsChangedEvent = {
442
+ id: string;
443
+ timestamp: number;
444
+ domain: "space";
445
+ type: "space.ports.changed";
446
+ requestId?: string | null;
447
+ spaceId: string;
448
+ sessionId?: string | null;
449
+ payload: SpacePortsChangedPayload;
450
+ };
451
+ export type RealtimeServerEvent = SystemReadyEvent | SystemAuthOkEvent | SystemRequestErrorEvent | SystemPongEvent | SystemAckOkEvent | SessionRequestAcceptedEvent | SessionRequestErrorEvent | SessionTurnProgressEvent | SessionTurnPatchEvent | SessionTurnSnapshotEvent | SessionTurnErrorEvent | SessionTurnUpdatedEvent | SessionTurnFinalizedEvent | SessionMessagePersistedEvent | SpaceFsChangedEvent | SpacePortsChangedEvent;
378
452
  export type WsServerEnvelope = RealtimeEnvelope;
379
453
  export type ChannelServerEnvelope = ChannelEnvelope;
@@ -105,3 +105,19 @@ export const realtimeCompactFrameSchema = z.discriminatedUnion("t", [
105
105
  v: z.unknown().optional(),
106
106
  }),
107
107
  ]);
108
+ const getNonEmptyString = (value) => typeof value === "string" && value.trim() ? value : null;
109
+ export const getSessionTurnPatchStreamKey = (input, options = {}) => {
110
+ const turnId = getNonEmptyString(input.turnId);
111
+ const messageKey = getNonEmptyString(input.messageId) ??
112
+ getNonEmptyString(input.sourceMessageId) ??
113
+ getNonEmptyString(input.anchorUserMessageId) ??
114
+ (typeof input.messageOrdinal === "number" && Number.isFinite(input.messageOrdinal)
115
+ ? `ordinal:${input.messageOrdinal}`
116
+ : null);
117
+ if (turnId && messageKey)
118
+ return `${turnId}:${messageKey}`;
119
+ const streamKey = messageKey ?? turnId;
120
+ if (streamKey)
121
+ return streamKey;
122
+ return options.includeSessionFallback ? getNonEmptyString(input.sessionId) : null;
123
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub-protocol",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Shared protocol definitions for the Cohub agent collaboration platform.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -52,6 +52,10 @@
52
52
  "./fs": {
53
53
  "types": "./dist/fs/index.d.ts",
54
54
  "default": "./dist/fs/index.js"
55
+ },
56
+ "./ports": {
57
+ "types": "./dist/ports/index.d.ts",
58
+ "default": "./dist/ports/index.js"
55
59
  }
56
60
  },
57
61
  "types": "./dist/index.d.ts",