@builder.io/ai-utils 0.3.9 → 0.3.10

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.
@@ -0,0 +1,174 @@
1
+ import type {
2
+ BuilderContent,
3
+ BuilderElement,
4
+ Component,
5
+ } from "@builder.io/sdk";
6
+ import type { Message, MessageParam, Attachment } from "./messages.js";
7
+ import type { BuilderModel } from "./events.js";
8
+
9
+ export type { BuilderContent, BuilderElement, Component };
10
+
11
+ export interface CompletionOptions {
12
+ /**
13
+ * How this assistant is being used. For example, "content-editor"
14
+ * is used when the assistant is being used in the Builder.io content editor.
15
+ */
16
+ assistantType?: string;
17
+
18
+ /**
19
+ * LLM Model identifier to lookup which sdk and model to use.
20
+ * If not provided the default model will be used.
21
+ * Note: This is not the Builder.io data model.
22
+ */
23
+ modelId?: string;
24
+
25
+ /**
26
+ * The unique LOCAL identifier of the thread to submit the user message to.
27
+ * This is used to identify the thread with our own id (openai assistant id is different)
28
+ */
29
+ id: string;
30
+
31
+ /**
32
+ * The unique OPENAI assistant id of the thread to submit the user message to.
33
+ * If the assistantThreadId is not provided, a new thread will be created.
34
+ */
35
+ assistantThreadId?: string;
36
+
37
+ /**
38
+ * The message history of the conversation, user prompt then assistant response.
39
+ * The messages are ordered from oldest to newest. The last message in the array
40
+ * is the message that the user has just sent.
41
+ */
42
+ messages: (MessageParam | Message)[];
43
+
44
+ /**
45
+ * Which platform (framework) the the user has choosen to get help with.
46
+ */
47
+ platformId?: string;
48
+
49
+ /**
50
+ * The user id of the user sending the message.
51
+ * This is used to track the user's progress in the conversation.
52
+ * User id is stored in localStorage for this domain, its not the builder user id.
53
+ */
54
+ userId: string;
55
+
56
+ /**
57
+ * The state of the builder editor.
58
+ */
59
+ builderState?: BuilderEditorState;
60
+
61
+ /**
62
+ * Additional console logs
63
+ */
64
+ debug?: boolean;
65
+
66
+ /**
67
+ * Date.now() timestamp of when the assistant was started.
68
+ * This is used to calculate the time taken between all events.
69
+ */
70
+ startMs?: number;
71
+ /**
72
+ * If events should be streamed back throughout the process.
73
+ *
74
+ * Setting to `false` will skip any intermediate processing and emitting
75
+ * events while collecting LLM deltas, but will only emit the final result.
76
+ *
77
+ * Defaults to `true`.
78
+ */
79
+ stream?: boolean;
80
+ /**
81
+ * Provide a system prompt id to lookup a pre-defined system prompt
82
+ * text sent to the LLM. Must be a pre-defined system prompt id!
83
+ */
84
+ systemPromptIds?: {
85
+ "content-edit"?: string;
86
+ };
87
+ /**
88
+ * Option on how this call should handle the conversation thread.
89
+ *
90
+ * `persist`:
91
+ * - When there is no CompletionOptions `id`, it'll create a new thread id
92
+ * - When given an existing `id`, it'll look up the past thread messages and prefix the messages
93
+ *
94
+ * `ephemeral`:
95
+ * - Creates a new conversation each time, ignoring any existing thread history
96
+ * - Will not save the conversation for future use
97
+ *
98
+ * Defaults to `persist`
99
+ */
100
+ thread?: "persist" | "ephemeral";
101
+
102
+ attachments?: Attachment[];
103
+ }
104
+
105
+ export interface BuilderEditorState {
106
+ /**
107
+ * The active locale of the builder editor.
108
+ */
109
+ activeLocale?: string;
110
+ /**
111
+ * The locale of the provided builder content.
112
+ */
113
+ contentLocale?: string;
114
+ /**
115
+ * Top level Builder content. The data.blocks array contains the BuilderElement.
116
+ */
117
+ content?: BuilderContent;
118
+ /**
119
+ * Builder custom components.
120
+ */
121
+ components?: Component[];
122
+ /**
123
+ * Builder design tokens.
124
+ */
125
+ designTokens?: Record<string, string>;
126
+ /**
127
+ * Builder model. (not the LLM model)
128
+ */
129
+ model?: BuilderModel;
130
+ /**
131
+ * Other models in the Builder account
132
+ */
133
+ otherModels?: BuilderModel[];
134
+ /**
135
+ * The URL that the Builder content preview is pointing to.
136
+ */
137
+ previewUrl?: string;
138
+ /**
139
+ * Selected ids in the builder.
140
+ */
141
+ selectedIds?: string[];
142
+ /**
143
+ * Builder space id.
144
+ */
145
+ spaceId?: string;
146
+ /**
147
+ * Builder user id.
148
+ */
149
+ userId?: string;
150
+ /**
151
+ * Email of the user in the builder.
152
+ */
153
+ userEmail?: string;
154
+ /**
155
+ * User's jobs
156
+ */
157
+ userJobs?: string[];
158
+ /**
159
+ * Builder session id.
160
+ */
161
+ sessionId?: string;
162
+ /**
163
+ * Custom instructions that could be add into the prompt.
164
+ */
165
+ customInstructions?: Record<string, string>;
166
+
167
+ // A URL to use as design inspiration when generating content
168
+ styleInspirationURL?: string;
169
+
170
+ /**
171
+ * All targeting attributes of the content.
172
+ */
173
+ allTargetingAttributes?: Record<string, any>;
174
+ }
package/src/events.ts ADDED
@@ -0,0 +1,474 @@
1
+ import type { BuilderContent, BuilderElement } from "@builder.io/sdk";
2
+ import type { AssistantMessage } from "./messages.js";
3
+ import type { AssistantSettings } from "./settings.js";
4
+
5
+ export type BuilderAssistantEventHandler = (ev: BuilderAssistantEvent) => void;
6
+
7
+ export type BuilderAssistantEvent =
8
+ | AssistantCompletionResultEvent
9
+ | AssistantErrorEvent
10
+ | AssistantStreamErrorEvent
11
+ | AppCloseEvent
12
+ | AppMessagesClickEvent
13
+ | AppMessagesGenerationEvent
14
+ | AppMessageEditCustomInstructionsEvent
15
+ | AppPromptAbortEvent
16
+ | AppPromptFocusEvent
17
+ | AppPromptSubmitEvent
18
+ | AppReadyEvent
19
+ | AppSettingsSetEvent
20
+ | AppThreadNewEvent
21
+ | AssistantStatsEvent
22
+ | AssistantThemeEvent
23
+ | BuilderEditorAuthEvent
24
+ | BuilderEditorStateEvent
25
+ | ContentUpdateEvent
26
+ | ContentApplySnapshotEvent
27
+ | ModelUndoEvent
28
+ | ModelRedoEvent
29
+ | ResultEvent
30
+ | ThreadCreatedEvent
31
+ | ThreadMessageCompletedEvent
32
+ | ThreadMessageCreatedEvent
33
+ | ThreadMessageDeltaEvent
34
+ | ThreadMessageFeedbackEvent
35
+ | ThreadRunStepCreatedEvent
36
+ | ThreadRunStepDeltaEvent
37
+ | AppAcceptChangeEvent
38
+ | AppAcceptRejectEvent
39
+ | AssistantTrackEvent
40
+ | AssistantEditorAuthMessage
41
+ | AppAttachmentTemplateEvent
42
+ | ThreadMessageRetryEvent
43
+ | AppFigmaImportEvent
44
+ | AppWebImportEvent
45
+ | AppAiTemplatesEvent
46
+ | AssistantContentInitialEvent
47
+ | ThreadMessageSummaryEvent
48
+ | AssistantHeartbeatEvent
49
+ | ShowUpgradeDialogEvent;
50
+
51
+ export interface AssistantCompletionResultEvent {
52
+ type: "assistant.result";
53
+ data: {
54
+ content?: BuilderContent;
55
+ stats?: AssistantStats;
56
+ };
57
+ resolveId?: string;
58
+ }
59
+
60
+ export interface AssistantError {
61
+ message: string;
62
+ status?: number;
63
+ }
64
+
65
+ export interface AssistantErrorEvent {
66
+ type: "assistant.error";
67
+ data: AssistantError;
68
+ }
69
+
70
+ export interface AssistantStreamErrorEvent {
71
+ type: "assistant.stream.error";
72
+ data: AssistantError;
73
+ }
74
+
75
+ export interface AppFigmaImportEvent {
76
+ type: "assistant.app.figmaImport";
77
+ }
78
+
79
+ export interface AppWebImportEvent {
80
+ type: "assistant.app.webImport";
81
+ }
82
+
83
+ export interface AppAiTemplatesEvent {
84
+ type: "assistant.app.aiTemplates";
85
+ }
86
+
87
+ export interface AssistantTrackEvent {
88
+ type: "assistant.track";
89
+ data: {
90
+ name: string;
91
+ properties: Record<string, any>;
92
+ };
93
+ }
94
+
95
+ export interface AssistantThemeEvent {
96
+ type: "assistant.app.theme.update";
97
+ data: {
98
+ theme: string;
99
+ };
100
+ }
101
+
102
+ export interface AppCloseEvent {
103
+ type: "assistant.app.close";
104
+ }
105
+
106
+ export interface AppMessagesClickEvent {
107
+ type: "assistant.app.messages.click";
108
+ }
109
+
110
+ export interface ShowUpgradeDialogEvent {
111
+ type: "assistant.app.showUpgradeDialog";
112
+ }
113
+
114
+ export interface AppAcceptChangeEvent {
115
+ type: "assistant.app.change.accept";
116
+ }
117
+ export interface AppAcceptRejectEvent {
118
+ type: "assistant.app.change.reject";
119
+ }
120
+
121
+ export interface AppMessageEditCustomInstructionsEvent {
122
+ type: "assistant.app.messages.editCustomInstructions";
123
+ }
124
+
125
+ export interface AppAttachmentTemplateEvent {
126
+ type: "assistant.app.attachment.template";
127
+ data: {
128
+ id: number;
129
+ name: string;
130
+ };
131
+ }
132
+
133
+ export interface AppMessagesGenerationEvent {
134
+ type: "assistant.app.messages.generation";
135
+ data: {
136
+ state: GenerationState;
137
+ };
138
+ }
139
+
140
+ /**
141
+ * idle: no messages are being generated or queued to be generated
142
+ *
143
+ * queued: messages have been sent to the LLM, but no response has been received yet
144
+ *
145
+ * generating: messages are actively being generated and streaming back to the UI
146
+ */
147
+ export type GenerationState = "idle" | "queued" | "generating";
148
+
149
+ export interface AppPromptAbortEvent {
150
+ type: "assistant.app.prompt.abort";
151
+ }
152
+
153
+ export interface AppPromptFocusEvent {
154
+ type: "assistant.app.prompt.focus";
155
+ }
156
+
157
+ export interface AppPromptSubmitEvent {
158
+ type: "assistant.app.prompt.submit";
159
+ data: {
160
+ prompt: string;
161
+ attachments: any[];
162
+ };
163
+ }
164
+
165
+ export interface AppReadyEvent {
166
+ type: "assistant.app.ready";
167
+ }
168
+
169
+ export interface AppSettingsSetEvent {
170
+ type: "assistant.app.settings.set";
171
+ data: Partial<AssistantSettings>;
172
+ }
173
+
174
+ export interface AppThreadNewEvent {
175
+ type: "assistant.app.thread.new";
176
+ }
177
+
178
+ export interface AssistantEditorAuthMessage {
179
+ type: "assistant.editor.auth.update";
180
+ }
181
+
182
+ export interface BuilderEditorAuthEvent extends AwaitResultEvent {
183
+ type: "assistant.editor.auth";
184
+ }
185
+
186
+ export interface BuilderEditorStateEvent extends AwaitResultEvent {
187
+ type: "assistant.editor.state";
188
+ }
189
+
190
+ export interface AwaitResultEvent {
191
+ resolveId?: string;
192
+ }
193
+
194
+ export interface ResultEvent {
195
+ type: "assistant.result";
196
+ resolveId: string;
197
+ data: any;
198
+ }
199
+
200
+ export interface ContentCreatePatch {
201
+ parentId: string;
202
+ insertBeforeId: string;
203
+ element: BuilderElement;
204
+ }
205
+
206
+ export interface ContentApplySnapshot {
207
+ /**
208
+ * The id of the BuilderContent to apply the snapshot to
209
+ */
210
+ id: string;
211
+ /**
212
+ * Each snapshot can be either a full BuilderContent or individual BuilderElements.
213
+ * Order matters, as the snapshots will be applied in the order they are listed.
214
+ * The builder app will handle the logic of applying the snapshots in the correct order
215
+ * and to the right content/elements.
216
+ */
217
+ snapshots: (BuilderElement | BuilderContent)[];
218
+ }
219
+
220
+ export interface ContentApplySnapshotEvent {
221
+ type: "assistant.content.applysnapshot";
222
+ data: ContentApplySnapshot;
223
+ }
224
+
225
+ export interface ContentUpdateEvent {
226
+ type: "assistant.content.update";
227
+ data: ContentUpdatePatch[];
228
+ }
229
+
230
+ export type ContentUpdatePatch = ContentTsUpdateComponentPatch;
231
+
232
+ interface ContentPatchBase {
233
+ id: string;
234
+ nodeId?: string;
235
+ builderId?: string;
236
+ description?: string;
237
+ value: string;
238
+ displayValue?: string;
239
+ ts: number;
240
+ /**
241
+ * A change value is considered incomplete until we also parsed it's closing xml tag.
242
+ */
243
+ incomplete?: boolean;
244
+ /**
245
+ * If there was an error applying the patch, this will contain the error message.
246
+ */
247
+ error?: string;
248
+ }
249
+
250
+ export interface ContentTsUpdateComponentPatch extends ContentPatchBase {
251
+ type: "update_component";
252
+ }
253
+
254
+ export interface AssistantStatsEvent {
255
+ type: "assistant.stats";
256
+ data: AssistantStats;
257
+ }
258
+
259
+ export interface AssistantStats {
260
+ /**
261
+ * The unique id of the thread (not the openai threadId)
262
+ */
263
+ threadId: string;
264
+ /**
265
+ * The unique id of the completion, which is a combination of the user's prompt and assistant's response.
266
+ */
267
+ completionId: string;
268
+ /**
269
+ * The model id used to generate this completion.
270
+ */
271
+ modelId: string;
272
+ /**
273
+ * The assistant's response message.
274
+ */
275
+ assistantMessage: string;
276
+ /**
277
+ * The assistant's summary of what it did. This appears after assistantMessage
278
+ * as well as any changes it made.
279
+ */
280
+ assistantSummary: string;
281
+ /**
282
+ * The user's prompt message.
283
+ */
284
+ userMessage: string;
285
+ /**
286
+ * The index within the thread the assistant message is.
287
+ * For a first assistant message, the index will be 1 (the user message is index 0).
288
+ * For a second assistant message, the index will be 3 (the user message is index 2), and so on.
289
+ */
290
+ assistantMessageIndex: number;
291
+ /**
292
+ * The timestamp (Date.now()) of when the user first submitted their prompt.
293
+ */
294
+ userPromptMs: number;
295
+ /**
296
+ * The timestamp of the first assistant chunk in the response.
297
+ */
298
+ firstChunkMs: number;
299
+ /**
300
+ * The timestamp of the last assistant chunk in the response.
301
+ */
302
+ lastChunkMs: number;
303
+ /**
304
+ * The total number of chunks in the assistant's streamed response.
305
+ */
306
+ chunkCount: number;
307
+ /**
308
+ * The total number of characters in the generated prompt sent to the LLM.
309
+ */
310
+ promptLength: number;
311
+ /**
312
+ * The total number of characters in the assistant's response.
313
+ */
314
+ completionLength: number;
315
+ /**
316
+ * If the user provided custom instructions for the prompt.
317
+ */
318
+ hasCustomInstructions: boolean;
319
+ /**
320
+ * The deployed version.
321
+ */
322
+ version: string;
323
+ /**
324
+ * Error message if there was one.
325
+ */
326
+ errorMessage?: string;
327
+ /**
328
+ * Input tokens
329
+ */
330
+ inputTokens?: number;
331
+ /**
332
+ * Output tokens
333
+ */
334
+ outputTokens?: number;
335
+ /**
336
+ * Output tokens
337
+ */
338
+ completionCost?: number;
339
+ /**
340
+ * Number of streamed snapshots
341
+ */
342
+ streamedSnapshots?: number;
343
+ /**
344
+ * Number of cached input tokens
345
+ */
346
+ cacheInputTokens?: number;
347
+ /**
348
+ * Number of cached created tokens
349
+ */
350
+ cacheCreatedTokens?: number;
351
+ }
352
+
353
+ export interface ModelUndoEvent {
354
+ type: "assistant.model.undo";
355
+ }
356
+
357
+ export interface ModelRedoEvent {
358
+ type: "assistant.model.redo";
359
+ }
360
+
361
+ export interface BuilderModel {
362
+ name?: string;
363
+ friendlyName?: string;
364
+ description?: string;
365
+ type?: string;
366
+ fields?: BuilderModelField[];
367
+ }
368
+
369
+ export interface BuilderModelField {
370
+ name?: string;
371
+ type?: string;
372
+ description?: string;
373
+ }
374
+
375
+ export interface ThreadMessageFeedbackEvent {
376
+ type: "assistant.thread.message.feedback";
377
+ data: CompletionResponseFeedback;
378
+ }
379
+
380
+ export interface CompletionResponseFeedback {
381
+ userId: string;
382
+ builderUserId?: string;
383
+ builderEmail?: string;
384
+ responseId?: string;
385
+ frontendUrl: string | undefined;
386
+ frontendCommitId: string | undefined;
387
+ backendDomain?: string;
388
+ backendCommitId: string | undefined;
389
+ feedbackText: string;
390
+ sentiment?: "positive" | "negative";
391
+ }
392
+
393
+ export interface ThreadCreatedEvent {
394
+ type: "assistant.thread.created";
395
+ data: ThreadCreated;
396
+ }
397
+
398
+ export interface ThreadCreated {
399
+ platformId: string;
400
+ threadId: string;
401
+ vectorStoreId: string;
402
+ }
403
+
404
+ export interface ThreadMessageCreatedEvent {
405
+ type: "assistant.thread.message.created";
406
+ data: ThreadMessageCreated;
407
+ }
408
+
409
+ export interface ThreadMessageCreated {
410
+ id: string;
411
+ responseId: string;
412
+ threadId: string;
413
+ }
414
+
415
+ export interface ThreadMessageDeltaEvent {
416
+ type: "assistant.thread.message.delta";
417
+ data: ThreadMessageDelta;
418
+ }
419
+
420
+ // use this event to keep a streaming connection alive
421
+ export interface AssistantHeartbeatEvent {
422
+ type: "assistant.heartbeat";
423
+ }
424
+
425
+ export interface ThreadMessageDelta {
426
+ id: string;
427
+ text: string;
428
+ }
429
+
430
+ export interface ThreadMessageCompletedEvent {
431
+ type: "assistant.thread.message.completed";
432
+ data: ThreadMessageCompleted;
433
+ }
434
+
435
+ export interface ThreadMessageRetryEvent {
436
+ type: "assistant.thread.message.retry";
437
+ }
438
+
439
+ export interface ThreadMessageSummaryEvent {
440
+ type: "assistant.thread.message.summary.delta";
441
+ data: ThreadMessageDelta;
442
+ }
443
+
444
+ export interface ThreadMessageCompleted extends AssistantMessage {
445
+ platformId: string;
446
+ threadId: string;
447
+ commitId?: string;
448
+ }
449
+
450
+ export interface ThreadRunStepDeltaEvent {
451
+ type: "assistant.thread.run.step.delta";
452
+ data: ThreadMessageStepDelta;
453
+ }
454
+
455
+ export interface ThreadMessageStepDelta {
456
+ delta: any;
457
+ }
458
+
459
+ export interface ThreadRunStepCreatedEvent {
460
+ type: "assistant.thread.run.step.created";
461
+ }
462
+
463
+ export type DeepPartial<T> = T extends object
464
+ ? {
465
+ [P in keyof T]?: DeepPartial<T[P]>;
466
+ }
467
+ : T;
468
+
469
+ export interface AssistantContentInitialEvent {
470
+ type: "assistant.content.initial";
471
+ data: {
472
+ code: string;
473
+ };
474
+ }