@builder.io/ai-utils 0.81.3 → 0.83.0-dev.202607211718.99c5f9cf8

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.
Files changed (46) hide show
  1. package/package.json +1 -1
  2. package/src/acl-schema.d.ts +88 -0
  3. package/src/acl-schema.js +71 -0
  4. package/src/claw.d.ts +1 -0
  5. package/src/claw.js +9 -0
  6. package/src/claw.spec.js +11 -1
  7. package/src/codegen/investigation-context.d.ts +1 -1
  8. package/src/codegen.d.ts +10 -0
  9. package/src/codegen.js +2 -1
  10. package/src/completion.d.ts +2 -1
  11. package/src/connectivity/checks/http-check.d.ts +7 -0
  12. package/src/connectivity/checks/http-check.js +13 -5
  13. package/src/connectivity/checks/http-check.spec.js +58 -0
  14. package/src/connectivity/environment.js +6 -0
  15. package/src/connectivity/node.d.ts +1 -1
  16. package/src/connectivity/node.js +1 -1
  17. package/src/connectivity/run-checks.js +13 -6
  18. package/src/connectivity/targets.d.ts +11 -1
  19. package/src/connectivity/targets.js +34 -1
  20. package/src/connectivity/targets.spec.js +51 -1
  21. package/src/connectivity/types.d.ts +17 -1
  22. package/src/editor-ai.d.ts +53 -0
  23. package/src/editor-ai.js +69 -0
  24. package/src/editor-ai.test.d.ts +1 -0
  25. package/src/editor-ai.test.js +37 -0
  26. package/src/embeddings.d.ts +82 -0
  27. package/src/embeddings.js +106 -0
  28. package/src/embeddings.spec.d.ts +1 -0
  29. package/src/embeddings.spec.js +43 -0
  30. package/src/events.d.ts +27 -1
  31. package/src/events.js +8 -0
  32. package/src/index.d.ts +3 -0
  33. package/src/index.js +3 -0
  34. package/src/messages.d.ts +15 -0
  35. package/src/organization.d.ts +9 -0
  36. package/src/perf-report.d.ts +116 -0
  37. package/src/perf-report.js +122 -0
  38. package/src/projects.d.ts +109 -12
  39. package/src/projects.js +87 -9
  40. package/src/proxy.d.ts +1 -1
  41. package/src/realtime.d.ts +232 -0
  42. package/src/realtime.js +158 -0
  43. package/src/realtime.spec.d.ts +1 -0
  44. package/src/realtime.spec.js +122 -0
  45. package/src/vpc-peering.d.ts +49 -0
  46. package/src/vpc-peering.js +1 -0
@@ -0,0 +1,232 @@
1
+ import { z } from "zod";
2
+ export declare const BUILDER_REALTIME_MODEL: "gpt-realtime-2.1";
3
+ export declare const BUILDER_REALTIME_MAX_SDP_LENGTH = 256000;
4
+ export declare const BUILDER_REALTIME_MAX_SESSION_BYTES = 64000;
5
+ export declare const OpenAIRealtimeFunctionToolSchema: z.ZodObject<{
6
+ type: z.ZodLiteral<"function">;
7
+ name: z.ZodString;
8
+ description: z.ZodOptional<z.ZodString>;
9
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
10
+ strict: z.ZodOptional<z.ZodBoolean>;
11
+ }, z.core.$strip>;
12
+ export type OpenAIRealtimeFunctionTool = z.infer<typeof OpenAIRealtimeFunctionToolSchema>;
13
+ export declare const OpenAIRealtimeMcpToolSchema: z.ZodObject<{
14
+ type: z.ZodLiteral<"mcp">;
15
+ server_label: z.ZodString;
16
+ server_url: z.ZodOptional<z.ZodURL>;
17
+ server_description: z.ZodOptional<z.ZodString>;
18
+ authorization: z.ZodOptional<z.ZodString>;
19
+ allowed_tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
20
+ require_approval: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
21
+ always: "always";
22
+ never: "never";
23
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
24
+ }, z.core.$strip>;
25
+ export type OpenAIRealtimeMcpTool = z.infer<typeof OpenAIRealtimeMcpToolSchema>;
26
+ export declare const OpenAIRealtimeToolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
27
+ type: z.ZodLiteral<"function">;
28
+ name: z.ZodString;
29
+ description: z.ZodOptional<z.ZodString>;
30
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ strict: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strip>, z.ZodObject<{
33
+ type: z.ZodLiteral<"mcp">;
34
+ server_label: z.ZodString;
35
+ server_url: z.ZodOptional<z.ZodURL>;
36
+ server_description: z.ZodOptional<z.ZodString>;
37
+ authorization: z.ZodOptional<z.ZodString>;
38
+ allowed_tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
39
+ require_approval: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
40
+ always: "always";
41
+ never: "never";
42
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
43
+ }, z.core.$strip>], "type">;
44
+ export type OpenAIRealtimeTool = z.infer<typeof OpenAIRealtimeToolSchema>;
45
+ /**
46
+ * The subset of OpenAI's Realtime session configuration accepted by Builder
47
+ * Connect. Zod objects intentionally strip unknown keys before this config is
48
+ * forwarded to OpenAI.
49
+ */
50
+ export declare const OpenAIRealtimeSessionConfigSchema: z.ZodObject<{
51
+ type: z.ZodLiteral<"realtime">;
52
+ model: z.ZodLiteral<"gpt-realtime-2.1">;
53
+ output_modalities: z.ZodTuple<[z.ZodLiteral<"audio">], null>;
54
+ instructions: z.ZodOptional<z.ZodString>;
55
+ audio: z.ZodOptional<z.ZodObject<{
56
+ input: z.ZodOptional<z.ZodObject<{
57
+ format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
58
+ noise_reduction: z.ZodOptional<z.ZodNullable<z.ZodObject<{
59
+ type: z.ZodEnum<{
60
+ far_field: "far_field";
61
+ near_field: "near_field";
62
+ }>;
63
+ }, z.core.$strip>>>;
64
+ transcription: z.ZodOptional<z.ZodNullable<z.ZodObject<{
65
+ model: z.ZodLiteral<"gpt-4o-mini-transcribe">;
66
+ language: z.ZodOptional<z.ZodString>;
67
+ prompt: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>>>;
69
+ turn_detection: z.ZodOptional<z.ZodNullable<z.ZodObject<{
70
+ type: z.ZodEnum<{
71
+ semantic_vad: "semantic_vad";
72
+ server_vad: "server_vad";
73
+ }>;
74
+ threshold: z.ZodOptional<z.ZodNumber>;
75
+ prefix_padding_ms: z.ZodOptional<z.ZodNumber>;
76
+ silence_duration_ms: z.ZodOptional<z.ZodNumber>;
77
+ idle_timeout_ms: z.ZodOptional<z.ZodNumber>;
78
+ eagerness: z.ZodOptional<z.ZodEnum<{
79
+ auto: "auto";
80
+ high: "high";
81
+ low: "low";
82
+ medium: "medium";
83
+ }>>;
84
+ create_response: z.ZodOptional<z.ZodBoolean>;
85
+ interrupt_response: z.ZodOptional<z.ZodBoolean>;
86
+ }, z.core.$strip>>>;
87
+ }, z.core.$strip>>;
88
+ output: z.ZodOptional<z.ZodObject<{
89
+ format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
90
+ voice: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
91
+ id: z.ZodString;
92
+ }, z.core.$strip>]>>;
93
+ speed: z.ZodOptional<z.ZodNumber>;
94
+ }, z.core.$strip>>;
95
+ }, z.core.$strip>>;
96
+ tools: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
97
+ type: z.ZodLiteral<"function">;
98
+ name: z.ZodString;
99
+ description: z.ZodOptional<z.ZodString>;
100
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
101
+ strict: z.ZodOptional<z.ZodBoolean>;
102
+ }, z.core.$strip>, z.ZodObject<{
103
+ type: z.ZodLiteral<"mcp">;
104
+ server_label: z.ZodString;
105
+ server_url: z.ZodOptional<z.ZodURL>;
106
+ server_description: z.ZodOptional<z.ZodString>;
107
+ authorization: z.ZodOptional<z.ZodString>;
108
+ allowed_tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
109
+ require_approval: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
110
+ always: "always";
111
+ never: "never";
112
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
113
+ }, z.core.$strip>], "type">>>;
114
+ tool_choice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
115
+ auto: "auto";
116
+ none: "none";
117
+ required: "required";
118
+ }>, z.ZodObject<{
119
+ type: z.ZodLiteral<"function">;
120
+ name: z.ZodString;
121
+ }, z.core.$strip>, z.ZodObject<{
122
+ type: z.ZodLiteral<"mcp">;
123
+ server_label: z.ZodString;
124
+ name: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strip>]>>;
126
+ max_output_tokens: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inf">, z.ZodNumber]>>;
127
+ prompt: z.ZodOptional<z.ZodNullable<z.ZodObject<{
128
+ id: z.ZodString;
129
+ version: z.ZodOptional<z.ZodString>;
130
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
131
+ }, z.core.$strip>>>;
132
+ tracing: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
133
+ truncation: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
134
+ auto: "auto";
135
+ disabled: "disabled";
136
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
137
+ include: z.ZodOptional<z.ZodArray<z.ZodString>>;
138
+ }, z.core.$strip>;
139
+ export type OpenAIRealtimeSessionConfig = z.infer<typeof OpenAIRealtimeSessionConfigSchema>;
140
+ export declare const BuilderRealtimeSessionRequestSchema: z.ZodObject<{
141
+ sdp: z.ZodString;
142
+ session: z.ZodObject<{
143
+ type: z.ZodLiteral<"realtime">;
144
+ model: z.ZodLiteral<"gpt-realtime-2.1">;
145
+ output_modalities: z.ZodTuple<[z.ZodLiteral<"audio">], null>;
146
+ instructions: z.ZodOptional<z.ZodString>;
147
+ audio: z.ZodOptional<z.ZodObject<{
148
+ input: z.ZodOptional<z.ZodObject<{
149
+ format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
150
+ noise_reduction: z.ZodOptional<z.ZodNullable<z.ZodObject<{
151
+ type: z.ZodEnum<{
152
+ far_field: "far_field";
153
+ near_field: "near_field";
154
+ }>;
155
+ }, z.core.$strip>>>;
156
+ transcription: z.ZodOptional<z.ZodNullable<z.ZodObject<{
157
+ model: z.ZodLiteral<"gpt-4o-mini-transcribe">;
158
+ language: z.ZodOptional<z.ZodString>;
159
+ prompt: z.ZodOptional<z.ZodString>;
160
+ }, z.core.$strip>>>;
161
+ turn_detection: z.ZodOptional<z.ZodNullable<z.ZodObject<{
162
+ type: z.ZodEnum<{
163
+ semantic_vad: "semantic_vad";
164
+ server_vad: "server_vad";
165
+ }>;
166
+ threshold: z.ZodOptional<z.ZodNumber>;
167
+ prefix_padding_ms: z.ZodOptional<z.ZodNumber>;
168
+ silence_duration_ms: z.ZodOptional<z.ZodNumber>;
169
+ idle_timeout_ms: z.ZodOptional<z.ZodNumber>;
170
+ eagerness: z.ZodOptional<z.ZodEnum<{
171
+ auto: "auto";
172
+ high: "high";
173
+ low: "low";
174
+ medium: "medium";
175
+ }>>;
176
+ create_response: z.ZodOptional<z.ZodBoolean>;
177
+ interrupt_response: z.ZodOptional<z.ZodBoolean>;
178
+ }, z.core.$strip>>>;
179
+ }, z.core.$strip>>;
180
+ output: z.ZodOptional<z.ZodObject<{
181
+ format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
182
+ voice: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
183
+ id: z.ZodString;
184
+ }, z.core.$strip>]>>;
185
+ speed: z.ZodOptional<z.ZodNumber>;
186
+ }, z.core.$strip>>;
187
+ }, z.core.$strip>>;
188
+ tools: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
189
+ type: z.ZodLiteral<"function">;
190
+ name: z.ZodString;
191
+ description: z.ZodOptional<z.ZodString>;
192
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
193
+ strict: z.ZodOptional<z.ZodBoolean>;
194
+ }, z.core.$strip>, z.ZodObject<{
195
+ type: z.ZodLiteral<"mcp">;
196
+ server_label: z.ZodString;
197
+ server_url: z.ZodOptional<z.ZodURL>;
198
+ server_description: z.ZodOptional<z.ZodString>;
199
+ authorization: z.ZodOptional<z.ZodString>;
200
+ allowed_tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
201
+ require_approval: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
202
+ always: "always";
203
+ never: "never";
204
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
205
+ }, z.core.$strip>], "type">>>;
206
+ tool_choice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
207
+ auto: "auto";
208
+ none: "none";
209
+ required: "required";
210
+ }>, z.ZodObject<{
211
+ type: z.ZodLiteral<"function">;
212
+ name: z.ZodString;
213
+ }, z.core.$strip>, z.ZodObject<{
214
+ type: z.ZodLiteral<"mcp">;
215
+ server_label: z.ZodString;
216
+ name: z.ZodOptional<z.ZodString>;
217
+ }, z.core.$strip>]>>;
218
+ max_output_tokens: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"inf">, z.ZodNumber]>>;
219
+ prompt: z.ZodOptional<z.ZodNullable<z.ZodObject<{
220
+ id: z.ZodString;
221
+ version: z.ZodOptional<z.ZodString>;
222
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
223
+ }, z.core.$strip>>>;
224
+ tracing: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
225
+ truncation: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
226
+ auto: "auto";
227
+ disabled: "disabled";
228
+ }>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
229
+ include: z.ZodOptional<z.ZodArray<z.ZodString>>;
230
+ }, z.core.$strip>;
231
+ }, z.core.$strip>;
232
+ export type BuilderRealtimeSessionRequest = z.infer<typeof BuilderRealtimeSessionRequestSchema>;
@@ -0,0 +1,158 @@
1
+ import { z } from "zod";
2
+ export const BUILDER_REALTIME_MODEL = "gpt-realtime-2.1";
3
+ export const BUILDER_REALTIME_MAX_SDP_LENGTH = 256000;
4
+ export const BUILDER_REALTIME_MAX_SESSION_BYTES = 64000;
5
+ const utf8ByteLength = (value) => new TextEncoder().encode(value).length;
6
+ const boundedRecord = (maxBytes, message) => z.record(z.string(), z.unknown()).refine((value) => {
7
+ try {
8
+ return utf8ByteLength(JSON.stringify(value)) <= maxBytes;
9
+ }
10
+ catch (_a) {
11
+ return false;
12
+ }
13
+ }, { message });
14
+ const RealtimeAudioFormatSchema = z.union([
15
+ z.string().min(1).max(128),
16
+ boundedRecord(2048, "Audio format configuration is too large"),
17
+ ]);
18
+ const RealtimeInputAudioSchema = z.object({
19
+ format: RealtimeAudioFormatSchema.optional(),
20
+ noise_reduction: z
21
+ .object({
22
+ type: z.enum(["near_field", "far_field"]),
23
+ })
24
+ .nullable()
25
+ .optional(),
26
+ transcription: z
27
+ .object({
28
+ model: z.literal("gpt-4o-mini-transcribe"),
29
+ language: z.string().min(1).max(32).optional(),
30
+ prompt: z.string().max(4096).optional(),
31
+ })
32
+ .nullable()
33
+ .optional(),
34
+ turn_detection: z
35
+ .object({
36
+ type: z.enum(["server_vad", "semantic_vad"]),
37
+ threshold: z.number().min(0).max(1).optional(),
38
+ prefix_padding_ms: z.number().int().min(0).max(10000).optional(),
39
+ silence_duration_ms: z.number().int().min(0).max(60000).optional(),
40
+ idle_timeout_ms: z.number().int().min(0).max(3600000).optional(),
41
+ eagerness: z.enum(["low", "medium", "high", "auto"]).optional(),
42
+ create_response: z.boolean().optional(),
43
+ interrupt_response: z.boolean().optional(),
44
+ })
45
+ .nullable()
46
+ .optional(),
47
+ });
48
+ const RealtimeOutputAudioSchema = z.object({
49
+ format: RealtimeAudioFormatSchema.optional(),
50
+ voice: z
51
+ .union([
52
+ z.string().min(1).max(128),
53
+ z.object({ id: z.string().min(1).max(256) }),
54
+ ])
55
+ .optional(),
56
+ speed: z.number().positive().max(4).optional(),
57
+ });
58
+ export const OpenAIRealtimeFunctionToolSchema = z.object({
59
+ type: z.literal("function"),
60
+ name: z
61
+ .string()
62
+ .min(1)
63
+ .max(64)
64
+ .regex(/^[a-zA-Z0-9_-]+$/),
65
+ description: z.string().max(4096).optional(),
66
+ parameters: boundedRecord(32000, "Realtime tool parameter schema is too large").optional(),
67
+ strict: z.boolean().optional(),
68
+ });
69
+ export const OpenAIRealtimeMcpToolSchema = z.object({
70
+ type: z.literal("mcp"),
71
+ server_label: z.string().min(1).max(128),
72
+ server_url: z.url().max(2048).optional(),
73
+ server_description: z.string().max(4096).optional(),
74
+ authorization: z.string().min(1).max(8192).optional(),
75
+ allowed_tools: z
76
+ .union([
77
+ z.array(z.string().min(1).max(128)).max(64),
78
+ boundedRecord(8000, "MCP allowed-tools configuration is too large"),
79
+ ])
80
+ .optional(),
81
+ require_approval: z
82
+ .union([
83
+ z.enum(["always", "never"]),
84
+ boundedRecord(8000, "MCP approval configuration is too large"),
85
+ ])
86
+ .optional(),
87
+ });
88
+ export const OpenAIRealtimeToolSchema = z.discriminatedUnion("type", [
89
+ OpenAIRealtimeFunctionToolSchema,
90
+ OpenAIRealtimeMcpToolSchema,
91
+ ]);
92
+ const OpenAIRealtimeToolChoiceSchema = z.union([
93
+ z.enum(["auto", "none", "required"]),
94
+ z.object({
95
+ type: z.literal("function"),
96
+ name: z.string().min(1).max(64),
97
+ }),
98
+ z.object({
99
+ type: z.literal("mcp"),
100
+ server_label: z.string().min(1).max(128),
101
+ name: z.string().min(1).max(128).optional(),
102
+ }),
103
+ ]);
104
+ /**
105
+ * The subset of OpenAI's Realtime session configuration accepted by Builder
106
+ * Connect. Zod objects intentionally strip unknown keys before this config is
107
+ * forwarded to OpenAI.
108
+ */
109
+ export const OpenAIRealtimeSessionConfigSchema = z
110
+ .object({
111
+ type: z.literal("realtime"),
112
+ model: z.literal(BUILDER_REALTIME_MODEL),
113
+ output_modalities: z.tuple([z.literal("audio")]),
114
+ instructions: z.string().max(32000).optional(),
115
+ audio: z
116
+ .object({
117
+ input: RealtimeInputAudioSchema.optional(),
118
+ output: RealtimeOutputAudioSchema.optional(),
119
+ })
120
+ .optional(),
121
+ tools: z.array(OpenAIRealtimeToolSchema).max(32).optional(),
122
+ tool_choice: OpenAIRealtimeToolChoiceSchema.optional(),
123
+ max_output_tokens: z
124
+ .union([z.literal("inf"), z.number().int().min(1).max(4096)])
125
+ .optional(),
126
+ prompt: z
127
+ .object({
128
+ id: z.string().min(1).max(256),
129
+ version: z.string().min(1).max(128).optional(),
130
+ variables: boundedRecord(16000, "Realtime prompt variables are too large").optional(),
131
+ })
132
+ .nullable()
133
+ .optional(),
134
+ tracing: z
135
+ .union([
136
+ z.literal("auto"),
137
+ boundedRecord(8000, "Realtime tracing configuration is too large"),
138
+ ])
139
+ .nullable()
140
+ .optional(),
141
+ truncation: z
142
+ .union([
143
+ z.enum(["auto", "disabled"]),
144
+ boundedRecord(2048, "Realtime truncation configuration is too large"),
145
+ ])
146
+ .optional(),
147
+ include: z.array(z.string().min(1).max(256)).max(16).optional(),
148
+ })
149
+ .refine((session) => utf8ByteLength(JSON.stringify(session)) <=
150
+ BUILDER_REALTIME_MAX_SESSION_BYTES, { message: "Realtime session configuration is too large" });
151
+ export const BuilderRealtimeSessionRequestSchema = z.object({
152
+ sdp: z
153
+ .string()
154
+ .min(1)
155
+ .max(BUILDER_REALTIME_MAX_SDP_LENGTH)
156
+ .refine((sdp) => sdp.trim().length > 0, { message: "SDP cannot be blank" }),
157
+ session: OpenAIRealtimeSessionConfigSchema,
158
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,122 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { BUILDER_REALTIME_MAX_SDP_LENGTH, BuilderRealtimeSessionRequestSchema, OpenAIRealtimeSessionConfigSchema, } from "./realtime.js";
3
+ const validSession = {
4
+ type: "realtime",
5
+ model: "gpt-realtime-2.1",
6
+ output_modalities: ["audio"],
7
+ instructions: "Help the user operate their Builder app.",
8
+ };
9
+ describe("BuilderRealtimeSessionRequestSchema", () => {
10
+ it("accepts a bounded audio session with tools", () => {
11
+ var _a;
12
+ const result = BuilderRealtimeSessionRequestSchema.parse({
13
+ sdp: "v=0\r\no=- 1 1 IN IP4 127.0.0.1",
14
+ session: {
15
+ ...validSession,
16
+ audio: {
17
+ input: {
18
+ turn_detection: {
19
+ type: "semantic_vad",
20
+ eagerness: "auto",
21
+ create_response: true,
22
+ interrupt_response: true,
23
+ },
24
+ },
25
+ output: { voice: "marin" },
26
+ },
27
+ tools: [
28
+ {
29
+ type: "function",
30
+ name: "navigate",
31
+ description: "Navigate within the app",
32
+ parameters: {
33
+ type: "object",
34
+ properties: { path: { type: "string" } },
35
+ required: ["path"],
36
+ },
37
+ },
38
+ ],
39
+ },
40
+ });
41
+ expect(result.session.model).toBe("gpt-realtime-2.1");
42
+ expect((_a = result.session.tools) === null || _a === void 0 ? void 0 : _a[0]).toMatchObject({
43
+ type: "function",
44
+ name: "navigate",
45
+ });
46
+ });
47
+ it("strips unknown request, session, and known nested config keys", () => {
48
+ const sdp = " v=0\r\n";
49
+ const result = BuilderRealtimeSessionRequestSchema.parse({
50
+ sdp,
51
+ ignoredRequestValue: "secret",
52
+ session: {
53
+ ...validSession,
54
+ ignoredSessionValue: "secret",
55
+ audio: {
56
+ output: {
57
+ voice: "marin",
58
+ ignoredAudioValue: "secret",
59
+ },
60
+ },
61
+ },
62
+ });
63
+ expect(result).toEqual({
64
+ sdp,
65
+ session: {
66
+ ...validSession,
67
+ audio: { output: { voice: "marin" } },
68
+ },
69
+ });
70
+ });
71
+ it.each([
72
+ [{ ...validSession, type: "transcription" }],
73
+ [{ ...validSession, model: "gpt-realtime" }],
74
+ [{ ...validSession, output_modalities: ["text"] }],
75
+ [{ ...validSession, output_modalities: ["audio", "text"] }],
76
+ [{ ...validSession, output_modalities: [] }],
77
+ ])("rejects unsupported sessions", (session) => {
78
+ expect(BuilderRealtimeSessionRequestSchema.safeParse({ sdp: "v=0", session })
79
+ .success).toBe(false);
80
+ });
81
+ it("rejects transcription models that do not match the metered rate", () => {
82
+ expect(OpenAIRealtimeSessionConfigSchema.safeParse({
83
+ ...validSession,
84
+ audio: {
85
+ input: { transcription: { model: "gpt-4o-transcribe" } },
86
+ },
87
+ }).success).toBe(false);
88
+ });
89
+ it("rejects empty and oversized SDP offers", () => {
90
+ expect(BuilderRealtimeSessionRequestSchema.safeParse({
91
+ sdp: " ",
92
+ session: validSession,
93
+ }).success).toBe(false);
94
+ expect(BuilderRealtimeSessionRequestSchema.safeParse({
95
+ sdp: "x".repeat(BUILDER_REALTIME_MAX_SDP_LENGTH + 1),
96
+ session: validSession,
97
+ }).success).toBe(false);
98
+ });
99
+ it("bounds instructions, tool count, and tool parameter schemas", () => {
100
+ expect(OpenAIRealtimeSessionConfigSchema.safeParse({
101
+ ...validSession,
102
+ instructions: "x".repeat(32001),
103
+ }).success).toBe(false);
104
+ expect(OpenAIRealtimeSessionConfigSchema.safeParse({
105
+ ...validSession,
106
+ tools: Array.from({ length: 33 }, (_, index) => ({
107
+ type: "function",
108
+ name: `tool_${index}`,
109
+ })),
110
+ }).success).toBe(false);
111
+ expect(OpenAIRealtimeSessionConfigSchema.safeParse({
112
+ ...validSession,
113
+ tools: [
114
+ {
115
+ type: "function",
116
+ name: "large_tool",
117
+ parameters: { description: "x".repeat(32001) },
118
+ },
119
+ ],
120
+ }).success).toBe(false);
121
+ });
122
+ });
@@ -0,0 +1,49 @@
1
+ /** Fields common to all VPC connectivity types. */
2
+ interface VpcConnectionBase {
3
+ id: string;
4
+ ownerId: string;
5
+ type: string;
6
+ gcpRegion: string;
7
+ customerDnsServers: string[];
8
+ proxyIp: string;
9
+ enabled: boolean;
10
+ createdAt: number;
11
+ updatedAt: number;
12
+ }
13
+ /** Traditional VPC Peering via bridge VPC. */
14
+ export interface VpcGcpPeering extends VpcConnectionBase {
15
+ type: "gcp-peering";
16
+ gcpProjectId: string;
17
+ gcpNetworkName: string;
18
+ bridgeCidr: string;
19
+ importCustomRoutes: boolean;
20
+ }
21
+ /**
22
+ * PSC Network Attachment — customer creates the network attachment in their VPC,
23
+ * our proxy VM connects to it via a PSC interface on nic1.
24
+ * No bridge VPC or bridge CIDR needed on our side.
25
+ */
26
+ export interface VpcGcpNetworkAttachment extends VpcConnectionBase {
27
+ type: "gcp-network-attachment";
28
+ gcpProjectId: string;
29
+ networkAttachmentName: string;
30
+ }
31
+ /** Discriminated union of all VPC connectivity types. */
32
+ export type VpcPeering = VpcGcpPeering | VpcGcpNetworkAttachment;
33
+ export interface CreateVpcGcpPeeringParams {
34
+ type: "gcp-peering";
35
+ gcpRegion: string;
36
+ gcpProjectId: string;
37
+ gcpNetworkName: string;
38
+ bridgeCidr: string;
39
+ customerDnsServers: string[];
40
+ importCustomRoutes?: boolean;
41
+ }
42
+ export interface CreateVpcGcpNetworkAttachmentParams {
43
+ type: "gcp-network-attachment";
44
+ gcpProjectId: string;
45
+ networkAttachmentName: string;
46
+ customerDnsServers: string[];
47
+ }
48
+ export type CreateVpcPeeringParams = CreateVpcGcpPeeringParams | CreateVpcGcpNetworkAttachmentParams;
49
+ export {};
@@ -0,0 +1 @@
1
+ export {};