@camox/api-contract 0.74.1 → 0.75.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.
- package/dist/router.d.ts +198 -1
- package/dist/threads.d.ts +18 -1
- package/dist/threads.js +15 -4
- package/package.json +1 -1
- package/src/threads.ts +16 -0
package/dist/router.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ import { AgentActivity, ConnectedAgentClient, ThreadSender, ThreadView } from "@
|
|
|
4
4
|
import { PiHarness, PiHarnessOptions } from "agents/harness/pi";
|
|
5
5
|
import { CapabilityStartContext, Lifecycle } from "agents/lifecycle";
|
|
6
6
|
import { WebSockets } from "agents/websockets";
|
|
7
|
+
import "@earendil-works/pi-ai";
|
|
8
|
+
import "@earendil-works/pi-ai/models";
|
|
9
|
+
import "@earendil-works/pi-durable/tools";
|
|
7
10
|
import { FileErrorCode } from "@earendil-works/pi-durable/env";
|
|
8
11
|
import "camox/_internal/sdkBundleName";
|
|
9
12
|
import "@camox/ai-tools";
|
|
@@ -38,6 +41,198 @@ declare class EdgeCachePurger extends DurableObject<Bindings> {
|
|
|
38
41
|
//#region ../../apps/api/src/lib/edge-cache-purges.d.ts
|
|
39
42
|
type EdgeCachePurgerNamespace = DurableObjectNamespace<EdgeCachePurger>;
|
|
40
43
|
//#endregion
|
|
44
|
+
//#region ../../apps/api/src/domains/attachments/schema.d.ts
|
|
45
|
+
/**
|
|
46
|
+
* An Attachment (ADR 0044): an image a member's Connected Agent uploaded for Camox's agent to
|
|
47
|
+
* see with one of its messages. Its bytes are a blob in the files bucket, under their own
|
|
48
|
+
* `attachments/` key space, and its row is apart from files', so it never shows among the
|
|
49
|
+
* project's Files. It becomes a File only when the agent puts it on the website.
|
|
50
|
+
*
|
|
51
|
+
* An Attachment no message used yet lasts a day from `createdAt`. A used one lasts as long as any
|
|
52
|
+
* thread whose message used it (`attachmentUses`).
|
|
53
|
+
*/
|
|
54
|
+
declare const attachments: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
55
|
+
name: "attachments";
|
|
56
|
+
schema: undefined;
|
|
57
|
+
columns: {
|
|
58
|
+
id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
59
|
+
name: "id";
|
|
60
|
+
tableName: "attachments";
|
|
61
|
+
dataType: "string";
|
|
62
|
+
columnType: "SQLiteText";
|
|
63
|
+
data: string;
|
|
64
|
+
driverParam: string;
|
|
65
|
+
notNull: true;
|
|
66
|
+
hasDefault: false;
|
|
67
|
+
isPrimaryKey: true;
|
|
68
|
+
isAutoincrement: false;
|
|
69
|
+
hasRuntimeDefault: false;
|
|
70
|
+
enumValues: [string, ...string[]];
|
|
71
|
+
baseColumn: never;
|
|
72
|
+
identity: undefined;
|
|
73
|
+
generated: undefined;
|
|
74
|
+
}, {}, {
|
|
75
|
+
length: undefined;
|
|
76
|
+
}>;
|
|
77
|
+
projectId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
78
|
+
name: "project_id";
|
|
79
|
+
tableName: "attachments";
|
|
80
|
+
dataType: "number";
|
|
81
|
+
columnType: "SQLiteInteger";
|
|
82
|
+
data: number;
|
|
83
|
+
driverParam: number;
|
|
84
|
+
notNull: true;
|
|
85
|
+
hasDefault: false;
|
|
86
|
+
isPrimaryKey: false;
|
|
87
|
+
isAutoincrement: false;
|
|
88
|
+
hasRuntimeDefault: false;
|
|
89
|
+
enumValues: undefined;
|
|
90
|
+
baseColumn: never;
|
|
91
|
+
identity: undefined;
|
|
92
|
+
generated: undefined;
|
|
93
|
+
}, {}, {}>;
|
|
94
|
+
memberId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
95
|
+
name: "member_id";
|
|
96
|
+
tableName: "attachments";
|
|
97
|
+
dataType: "string";
|
|
98
|
+
columnType: "SQLiteText";
|
|
99
|
+
data: string;
|
|
100
|
+
driverParam: string;
|
|
101
|
+
notNull: true;
|
|
102
|
+
hasDefault: false;
|
|
103
|
+
isPrimaryKey: false;
|
|
104
|
+
isAutoincrement: false;
|
|
105
|
+
hasRuntimeDefault: false;
|
|
106
|
+
enumValues: [string, ...string[]];
|
|
107
|
+
baseColumn: never;
|
|
108
|
+
identity: undefined;
|
|
109
|
+
generated: undefined;
|
|
110
|
+
}, {}, {
|
|
111
|
+
length: number | undefined;
|
|
112
|
+
}>;
|
|
113
|
+
filename: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
114
|
+
name: "filename";
|
|
115
|
+
tableName: "attachments";
|
|
116
|
+
dataType: "string";
|
|
117
|
+
columnType: "SQLiteText";
|
|
118
|
+
data: string;
|
|
119
|
+
driverParam: string;
|
|
120
|
+
notNull: true;
|
|
121
|
+
hasDefault: false;
|
|
122
|
+
isPrimaryKey: false;
|
|
123
|
+
isAutoincrement: false;
|
|
124
|
+
hasRuntimeDefault: false;
|
|
125
|
+
enumValues: [string, ...string[]];
|
|
126
|
+
baseColumn: never;
|
|
127
|
+
identity: undefined;
|
|
128
|
+
generated: undefined;
|
|
129
|
+
}, {}, {
|
|
130
|
+
length: undefined;
|
|
131
|
+
}>;
|
|
132
|
+
mimeType: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
133
|
+
name: "mime_type";
|
|
134
|
+
tableName: "attachments";
|
|
135
|
+
dataType: "string";
|
|
136
|
+
columnType: "SQLiteText";
|
|
137
|
+
data: "image/jpeg" | "image/png" | "image/svg+xml" | "image/webp";
|
|
138
|
+
driverParam: string;
|
|
139
|
+
notNull: true;
|
|
140
|
+
hasDefault: false;
|
|
141
|
+
isPrimaryKey: false;
|
|
142
|
+
isAutoincrement: false;
|
|
143
|
+
hasRuntimeDefault: false;
|
|
144
|
+
enumValues: [string, ...string[]];
|
|
145
|
+
baseColumn: never;
|
|
146
|
+
identity: undefined;
|
|
147
|
+
generated: undefined;
|
|
148
|
+
}, {}, {
|
|
149
|
+
length: number | undefined;
|
|
150
|
+
$type: "image/jpeg" | "image/png" | "image/svg+xml" | "image/webp";
|
|
151
|
+
}>;
|
|
152
|
+
size: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
153
|
+
name: "size";
|
|
154
|
+
tableName: "attachments";
|
|
155
|
+
dataType: "number";
|
|
156
|
+
columnType: "SQLiteInteger";
|
|
157
|
+
data: number;
|
|
158
|
+
driverParam: number;
|
|
159
|
+
notNull: true;
|
|
160
|
+
hasDefault: false;
|
|
161
|
+
isPrimaryKey: false;
|
|
162
|
+
isAutoincrement: false;
|
|
163
|
+
hasRuntimeDefault: false;
|
|
164
|
+
enumValues: undefined;
|
|
165
|
+
baseColumn: never;
|
|
166
|
+
identity: undefined;
|
|
167
|
+
generated: undefined;
|
|
168
|
+
}, {}, {}>;
|
|
169
|
+
blobKey: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
170
|
+
name: "blob_key";
|
|
171
|
+
tableName: "attachments";
|
|
172
|
+
dataType: "string";
|
|
173
|
+
columnType: "SQLiteText";
|
|
174
|
+
data: string;
|
|
175
|
+
driverParam: string;
|
|
176
|
+
notNull: true;
|
|
177
|
+
hasDefault: false;
|
|
178
|
+
isPrimaryKey: false;
|
|
179
|
+
isAutoincrement: false;
|
|
180
|
+
hasRuntimeDefault: false;
|
|
181
|
+
enumValues: [string, ...string[]];
|
|
182
|
+
baseColumn: never;
|
|
183
|
+
identity: undefined;
|
|
184
|
+
generated: undefined;
|
|
185
|
+
}, {}, {
|
|
186
|
+
length: number | undefined;
|
|
187
|
+
}>;
|
|
188
|
+
url: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
189
|
+
name: "url";
|
|
190
|
+
tableName: "attachments";
|
|
191
|
+
dataType: "string";
|
|
192
|
+
columnType: "SQLiteText";
|
|
193
|
+
data: string;
|
|
194
|
+
driverParam: string;
|
|
195
|
+
notNull: true;
|
|
196
|
+
hasDefault: false;
|
|
197
|
+
isPrimaryKey: false;
|
|
198
|
+
isAutoincrement: false;
|
|
199
|
+
hasRuntimeDefault: false;
|
|
200
|
+
enumValues: [string, ...string[]];
|
|
201
|
+
baseColumn: never;
|
|
202
|
+
identity: undefined;
|
|
203
|
+
generated: undefined;
|
|
204
|
+
}, {}, {
|
|
205
|
+
length: undefined;
|
|
206
|
+
}>;
|
|
207
|
+
createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
208
|
+
name: "created_at";
|
|
209
|
+
tableName: "attachments";
|
|
210
|
+
dataType: "number";
|
|
211
|
+
columnType: "SQLiteInteger";
|
|
212
|
+
data: number;
|
|
213
|
+
driverParam: number;
|
|
214
|
+
notNull: true;
|
|
215
|
+
hasDefault: false;
|
|
216
|
+
isPrimaryKey: false;
|
|
217
|
+
isAutoincrement: false;
|
|
218
|
+
hasRuntimeDefault: false;
|
|
219
|
+
enumValues: undefined;
|
|
220
|
+
baseColumn: never;
|
|
221
|
+
identity: undefined;
|
|
222
|
+
generated: undefined;
|
|
223
|
+
}, {}, {}>;
|
|
224
|
+
};
|
|
225
|
+
dialect: 'sqlite';
|
|
226
|
+
}>;
|
|
227
|
+
type Attachment = typeof attachments.$inferSelect;
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region ../../apps/api/src/domains/attachments/model-input.d.ts
|
|
230
|
+
/**
|
|
231
|
+
* An Attachment as a thread message carries it: what a model's label and the studio name it by,
|
|
232
|
+
* and where its bytes are.
|
|
233
|
+
*/
|
|
234
|
+
type MessageAttachment = Pick<Attachment, "id" | "filename" | "mimeType" | "url" | "blobKey">;
|
|
235
|
+
//#endregion
|
|
41
236
|
//#region ../../apps/api/src/domains/code/remote-env.d.ts
|
|
42
237
|
/** The operations sent as they are: every argument but the context is plain data. */
|
|
43
238
|
declare const SENT: ["absolutePath", "joinPath", "readTextFile", "readTextLines", "readBinaryFile", "writeFile", "appendFile", "truncateFile", "flushFile", "renameFile", "fileInfo", "listDir", "canonicalPath", "exists", "createDir", "remove"];
|
|
@@ -9543,13 +9738,15 @@ type OpeningSender = {
|
|
|
9543
9738
|
};
|
|
9544
9739
|
/**
|
|
9545
9740
|
* A message a draft's thread opens with: its text, the operation id it was sent with, and who
|
|
9546
|
-
* sent it. A Connected Agent's message may be its answer to the agent's questions (ADR 0042)
|
|
9741
|
+
* sent it. A Connected Agent's message may be its answer to the agent's questions (ADR 0042), and
|
|
9742
|
+
* may carry Attachments, images the model sees with it (ADR 0044).
|
|
9547
9743
|
*/
|
|
9548
9744
|
type OpeningMessage = {
|
|
9549
9745
|
operationId: string;
|
|
9550
9746
|
text: string;
|
|
9551
9747
|
from: OpeningSender;
|
|
9552
9748
|
answer?: boolean;
|
|
9749
|
+
attachments?: MessageAttachment[];
|
|
9553
9750
|
};
|
|
9554
9751
|
/**
|
|
9555
9752
|
* How the API opens a draft's thread with no studio connected (`Thread.open`): what it belongs
|
package/dist/threads.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DraftOutcome } from "./drafts.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { AgentEvent } from "@earendil-works/pi-durable";
|
|
4
3
|
import { Message } from "@earendil-works/pi-ai";
|
|
4
|
+
import { AgentEvent } from "@earendil-works/pi-durable";
|
|
5
5
|
//#region src/threads.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* The kind of the transcript entry recording an editor's message, with its sender and the
|
|
@@ -190,6 +190,14 @@ export declare const connectedAgentClientSchema: z.ZodObject<{
|
|
|
190
190
|
verified: z.ZodBoolean;
|
|
191
191
|
}, z.core.$strip>;
|
|
192
192
|
export type ConnectedAgentClient = z.infer<typeof connectedAgentClientSchema>;
|
|
193
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
194
|
+
export declare const messageAttachmentSchema: z.ZodObject<{
|
|
195
|
+
id: z.ZodString;
|
|
196
|
+
filename: z.ZodString;
|
|
197
|
+
mimeType: z.ZodString;
|
|
198
|
+
url: z.ZodString;
|
|
199
|
+
}, z.core.$strip>;
|
|
200
|
+
export type MessageAttachmentData = z.infer<typeof messageAttachmentSchema>;
|
|
193
201
|
/**
|
|
194
202
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
195
203
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -206,6 +214,12 @@ export declare const connectedAgentMessageDataSchema: z.ZodObject<{
|
|
|
206
214
|
}, z.core.$strip>;
|
|
207
215
|
operationId: z.ZodOptional<z.ZodString>;
|
|
208
216
|
answer: z.ZodOptional<z.ZodBoolean>;
|
|
217
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
218
|
+
id: z.ZodString;
|
|
219
|
+
filename: z.ZodString;
|
|
220
|
+
mimeType: z.ZodString;
|
|
221
|
+
url: z.ZodString;
|
|
222
|
+
}, z.core.$strip>>>;
|
|
209
223
|
}, z.core.$strip>;
|
|
210
224
|
export type ConnectedAgentMessageData = z.infer<typeof connectedAgentMessageDataSchema>;
|
|
211
225
|
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
@@ -350,6 +364,8 @@ export type ThreadMessage = {
|
|
|
350
364
|
client: ConnectedAgentClient;
|
|
351
365
|
text: string;
|
|
352
366
|
answer: boolean;
|
|
367
|
+
/** The images it carries for the agent to see, if any (ADR 0044). */
|
|
368
|
+
attachments?: MessageAttachmentData[];
|
|
353
369
|
} |
|
|
354
370
|
/** Camox's own message, starting a turn it began itself: why it did. */
|
|
355
371
|
{
|
|
@@ -502,6 +518,7 @@ type ThreadStep = {
|
|
|
502
518
|
client: ConnectedAgentClient;
|
|
503
519
|
text: string;
|
|
504
520
|
answer: boolean;
|
|
521
|
+
attachments?: MessageAttachmentData[];
|
|
505
522
|
} |
|
|
506
523
|
/** Camox starting a turn of its own, saying why. */
|
|
507
524
|
{
|
package/dist/threads.js
CHANGED
|
@@ -182,6 +182,13 @@ const connectedAgentClientSchema = z.object({
|
|
|
182
182
|
name: z.string(),
|
|
183
183
|
verified: z.boolean()
|
|
184
184
|
});
|
|
185
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
186
|
+
const messageAttachmentSchema = z.object({
|
|
187
|
+
id: z.string(),
|
|
188
|
+
filename: z.string(),
|
|
189
|
+
mimeType: z.string(),
|
|
190
|
+
url: z.string()
|
|
191
|
+
});
|
|
185
192
|
/**
|
|
186
193
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
187
194
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -190,7 +197,9 @@ const connectedAgentMessageDataSchema = z.object({
|
|
|
190
197
|
member: threadSenderSchema,
|
|
191
198
|
client: connectedAgentClientSchema,
|
|
192
199
|
operationId: z.string().optional(),
|
|
193
|
-
answer: z.boolean().optional()
|
|
200
|
+
answer: z.boolean().optional(),
|
|
201
|
+
/** The images the message carries for the agent to see, as studios list them (ADR 0044). */
|
|
202
|
+
attachments: z.array(messageAttachmentSchema).optional()
|
|
194
203
|
});
|
|
195
204
|
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
196
205
|
const pushDataSchema = z.object({
|
|
@@ -419,7 +428,8 @@ function threadStepOf(entry) {
|
|
|
419
428
|
verified: data.client.verified
|
|
420
429
|
},
|
|
421
430
|
text: editorTextOf(message.content),
|
|
422
|
-
answer: data.answer ?? false
|
|
431
|
+
answer: data.answer ?? false,
|
|
432
|
+
...data.attachments?.length && { attachments: data.attachments }
|
|
423
433
|
};
|
|
424
434
|
}
|
|
425
435
|
if (entry.kind === "camox.brief") return {
|
|
@@ -525,7 +535,8 @@ function threadViewOf({ steps, running, toolCalls = [], callingTools = false, ch
|
|
|
525
535
|
member: step.member,
|
|
526
536
|
client: step.client,
|
|
527
537
|
text: step.text,
|
|
528
|
-
answer: step.answer
|
|
538
|
+
answer: step.answer,
|
|
539
|
+
...step.attachments && { attachments: step.attachments }
|
|
529
540
|
});
|
|
530
541
|
waiting = step.id;
|
|
531
542
|
break;
|
|
@@ -761,4 +772,4 @@ function reduceThreadFrame(state, frame) {
|
|
|
761
772
|
}
|
|
762
773
|
|
|
763
774
|
//#endregion
|
|
764
|
-
export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, isSender, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
|
775
|
+
export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, isSender, messageAttachmentSchema, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
package/package.json
CHANGED
package/src/threads.ts
CHANGED
|
@@ -232,6 +232,15 @@ export const isSender = (data: unknown): data is ThreadSender =>
|
|
|
232
232
|
export const connectedAgentClientSchema = z.object({ name: z.string(), verified: z.boolean() });
|
|
233
233
|
export type ConnectedAgentClient = z.infer<typeof connectedAgentClientSchema>;
|
|
234
234
|
|
|
235
|
+
/** An Attachment a Connected Agent's message carries: an image the agent sees with it. */
|
|
236
|
+
export const messageAttachmentSchema = z.object({
|
|
237
|
+
id: z.string(),
|
|
238
|
+
filename: z.string(),
|
|
239
|
+
mimeType: z.string(),
|
|
240
|
+
url: z.string(),
|
|
241
|
+
});
|
|
242
|
+
export type MessageAttachmentData = z.infer<typeof messageAttachmentSchema>;
|
|
243
|
+
|
|
235
244
|
/**
|
|
236
245
|
* What a Connected Agent's message entry records: the member it acts as, its client, the
|
|
237
246
|
* operation id it was sent with, and whether it answers the agent's questions (ADR 0042).
|
|
@@ -241,6 +250,8 @@ export const connectedAgentMessageDataSchema = z.object({
|
|
|
241
250
|
client: connectedAgentClientSchema,
|
|
242
251
|
operationId: z.string().optional(),
|
|
243
252
|
answer: z.boolean().optional(),
|
|
253
|
+
/** The images the message carries for the agent to see, as studios list them (ADR 0044). */
|
|
254
|
+
attachments: z.array(messageAttachmentSchema).optional(),
|
|
244
255
|
});
|
|
245
256
|
export type ConnectedAgentMessageData = z.infer<typeof connectedAgentMessageDataSchema>;
|
|
246
257
|
|
|
@@ -326,6 +337,8 @@ export type ThreadMessage =
|
|
|
326
337
|
client: ConnectedAgentClient;
|
|
327
338
|
text: string;
|
|
328
339
|
answer: boolean;
|
|
340
|
+
/** The images it carries for the agent to see, if any (ADR 0044). */
|
|
341
|
+
attachments?: MessageAttachmentData[];
|
|
329
342
|
}
|
|
330
343
|
/** Camox's own message, starting a turn it began itself: why it did. */
|
|
331
344
|
| { id: string; from: "camox"; text: string }
|
|
@@ -441,6 +454,7 @@ type ThreadStep = { id: string } & (
|
|
|
441
454
|
client: ConnectedAgentClient;
|
|
442
455
|
text: string;
|
|
443
456
|
answer: boolean;
|
|
457
|
+
attachments?: MessageAttachmentData[];
|
|
444
458
|
}
|
|
445
459
|
/** Camox starting a turn of its own, saying why. */
|
|
446
460
|
| { type: "camox"; text: string }
|
|
@@ -618,6 +632,7 @@ function threadStepOf(entry: EntryRecord): ThreadStep | undefined {
|
|
|
618
632
|
client: { name: data.client.name, verified: data.client.verified },
|
|
619
633
|
text: editorTextOf(message.content),
|
|
620
634
|
answer: data.answer ?? false,
|
|
635
|
+
...(data.attachments?.length && { attachments: data.attachments }),
|
|
621
636
|
}
|
|
622
637
|
);
|
|
623
638
|
}
|
|
@@ -722,6 +737,7 @@ export function threadViewOf({
|
|
|
722
737
|
client: step.client,
|
|
723
738
|
text: step.text,
|
|
724
739
|
answer: step.answer,
|
|
740
|
+
...(step.attachments && { attachments: step.attachments }),
|
|
725
741
|
});
|
|
726
742
|
waiting = step.id;
|
|
727
743
|
break;
|