@builder.io/ai-utils 0.99.0 → 0.100.1
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/package.json +1 -1
- package/src/codegen.d.ts +75 -22
- package/src/codegen.js +42 -16
- package/src/events.d.ts +58 -2
- package/src/events.js +20 -0
- package/src/projects.d.ts +1300 -8
- package/src/projects.js +145 -11
- package/src/projects.test.js +76 -1
- package/src/publish-agent.d.ts +13 -0
- package/src/publish-agent.js +20 -0
- package/src/realtime.d.ts +118 -3
- package/src/realtime.js +70 -3
- package/src/realtime.spec.js +53 -5
package/src/projects.js
CHANGED
|
@@ -279,7 +279,10 @@ export const ShapeEffectSchema = z.discriminatedUnion("kind", [
|
|
|
279
279
|
}),
|
|
280
280
|
z.object({
|
|
281
281
|
kind: z.literal("attach-design-system"),
|
|
282
|
+
/** The permanent join key. */
|
|
282
283
|
designSystemId: z.string(),
|
|
284
|
+
/** What actually gets written: the field is matched by name downstream. */
|
|
285
|
+
designSystemName: z.string(),
|
|
283
286
|
}),
|
|
284
287
|
]);
|
|
285
288
|
export const ShapeOptionEffectSchema = z.object({
|
|
@@ -302,24 +305,93 @@ export const ShapeAnswerSchema = z.object({
|
|
|
302
305
|
questionId: z.string(),
|
|
303
306
|
optionId: z.string().optional(),
|
|
304
307
|
designSystemId: z.string().optional(),
|
|
308
|
+
/**
|
|
309
|
+
* Server-resolved from `designSystemId` against the caller's accessible
|
|
310
|
+
* design systems. `settings.designSystems` is matched by name downstream, so
|
|
311
|
+
* the id alone cannot be written there.
|
|
312
|
+
*/
|
|
313
|
+
designSystemName: z.string().optional(),
|
|
305
314
|
skipped: z.boolean(),
|
|
306
315
|
delegated: z.boolean(),
|
|
307
316
|
resolvedFrom: z.enum(["user", "llm"]),
|
|
308
317
|
llmOptionId: z.string().optional(),
|
|
309
318
|
guessOptionId: z.string().optional(),
|
|
310
319
|
});
|
|
320
|
+
const ShapeAnswerInputBaseSchema = ShapeAnswerSchema.pick({
|
|
321
|
+
questionId: true,
|
|
322
|
+
optionId: true,
|
|
323
|
+
designSystemId: true,
|
|
324
|
+
skipped: true,
|
|
325
|
+
delegated: true,
|
|
326
|
+
});
|
|
327
|
+
export const ShapeAnswerInputSchema = z.object({
|
|
328
|
+
...ShapeAnswerInputBaseSchema.shape,
|
|
329
|
+
questionId: ShapeAnswerInputBaseSchema.shape.questionId.trim().min(1),
|
|
330
|
+
optionId: ShapeAnswerInputBaseSchema.shape.optionId
|
|
331
|
+
.unwrap()
|
|
332
|
+
.trim()
|
|
333
|
+
.min(1)
|
|
334
|
+
.optional(),
|
|
335
|
+
designSystemId: ShapeAnswerInputBaseSchema.shape.designSystemId
|
|
336
|
+
.unwrap()
|
|
337
|
+
.trim()
|
|
338
|
+
.min(1)
|
|
339
|
+
.optional(),
|
|
340
|
+
});
|
|
341
|
+
export const GetShapeQuestionnaireOptionsSchema = z.object({
|
|
342
|
+
projectId: z.string().trim().min(1),
|
|
343
|
+
});
|
|
344
|
+
export const SubmitShapeAnswersOptionsSchema = z.object({
|
|
345
|
+
projectId: z.string().trim().min(1),
|
|
346
|
+
questionnaireId: z.string().trim().min(1),
|
|
347
|
+
answers: z.array(ShapeAnswerInputSchema).min(1),
|
|
348
|
+
});
|
|
349
|
+
/**
|
|
350
|
+
* A file the client writes into the container's working tree over the
|
|
351
|
+
* launch-server RPC. The server renders the body; the container performs the
|
|
352
|
+
* write; the agent only reads it.
|
|
353
|
+
*/
|
|
354
|
+
export const ShapeDecisionsFileSchema = z.object({
|
|
355
|
+
/** Repository-root relative. */
|
|
356
|
+
path: z.string().min(1),
|
|
357
|
+
contents: z.string().min(1),
|
|
358
|
+
});
|
|
359
|
+
export const SubmitShapeAnswersResponseSchema = z.object({
|
|
360
|
+
prompt: z.string().min(1),
|
|
361
|
+
instructionBlock: z.string().min(1).optional(),
|
|
362
|
+
decisionsFile: ShapeDecisionsFileSchema.optional(),
|
|
363
|
+
});
|
|
364
|
+
export const ShapeQuestionDecisionSchema = z.object({
|
|
365
|
+
questionId: z.string(),
|
|
366
|
+
ask: z.boolean(),
|
|
367
|
+
llmOptionId: z.string().optional(),
|
|
368
|
+
confidence: z.number().optional(),
|
|
369
|
+
guessOptionId: z.string(),
|
|
370
|
+
});
|
|
311
371
|
export const ShapeSessionSchema = z.object({
|
|
312
372
|
questionnaireId: z.string(),
|
|
313
373
|
catalogVersion: z.string().regex(/^\d{4}-\d{2}-\d{2}\.\d+$/),
|
|
314
374
|
source: z.enum(["static", "agent"]),
|
|
315
375
|
status: z.enum(["assembling", "pending", "resolved"]),
|
|
316
|
-
selection: z.enum(["llm", "fallback"]),
|
|
376
|
+
selection: z.enum(["llm", "fallback"]).optional(),
|
|
377
|
+
decisions: z.array(ShapeQuestionDecisionSchema).optional(),
|
|
317
378
|
questions: z.array(ShapeQuestionSchema),
|
|
318
379
|
initialPromptId: z.string(),
|
|
319
380
|
answers: z.array(ShapeAnswerSchema).optional(),
|
|
381
|
+
issuedAt: z.string().optional(),
|
|
320
382
|
assembledAt: z.string().optional(),
|
|
321
383
|
resolvedAt: z.string().optional(),
|
|
322
384
|
});
|
|
385
|
+
export const InitialPromptSchema = z.object({
|
|
386
|
+
id: z.string(),
|
|
387
|
+
projectId: z.string(),
|
|
388
|
+
branchName: z.string().optional(),
|
|
389
|
+
prompt: z.string(),
|
|
390
|
+
attachmentIds: z.array(z.string()).optional(),
|
|
391
|
+
createdBy: z.string(),
|
|
392
|
+
createdAt: z.number(),
|
|
393
|
+
deliveredAt: z.number().optional(),
|
|
394
|
+
});
|
|
323
395
|
export const ProjectRolePermissionsSchema = z
|
|
324
396
|
.object({
|
|
325
397
|
view: z.boolean().optional(),
|
|
@@ -861,8 +933,9 @@ export const getBranchState = (branch) => {
|
|
|
861
933
|
* Get the state of a project, checking `state` first and falling back to `deleted` for backwards compatibility.
|
|
862
934
|
*/
|
|
863
935
|
export const getProjectState = (project) => {
|
|
864
|
-
|
|
865
|
-
|
|
936
|
+
if (project.state)
|
|
937
|
+
return project.state;
|
|
938
|
+
return project.deleted ? "deleted" : "active";
|
|
866
939
|
};
|
|
867
940
|
/**
|
|
868
941
|
* Check if a branch is deleted, supporting both `state` and legacy `deleted` fields.
|
|
@@ -1753,6 +1826,17 @@ export const GetHostingAiUsageResponseSchema = z.object({
|
|
|
1753
1826
|
*/
|
|
1754
1827
|
coreSupportsGateway: z.boolean(),
|
|
1755
1828
|
token: HostingAiUsageTokenStatusSchema.nullable(),
|
|
1829
|
+
/**
|
|
1830
|
+
* The `AI_USAGE_MANAGED_PROD_ENV_KEYS` currently holding a value the deployed
|
|
1831
|
+
* site will see, names only. The client cannot derive this: the write endpoint
|
|
1832
|
+
* deliberately leaves the caller's project model stale, so anything projected
|
|
1833
|
+
* locally is wrong the moment two writes or an out-of-band env edit interleave.
|
|
1834
|
+
*
|
|
1835
|
+
* Absent on an API that predates the field, which a client must read as
|
|
1836
|
+
* "unknown" and not as "none": reading it as none pre-selects a mode whose
|
|
1837
|
+
* write deletes the customer's provider key.
|
|
1838
|
+
*/
|
|
1839
|
+
managedProdEnvKeys: z.array(z.string()).optional(),
|
|
1756
1840
|
});
|
|
1757
1841
|
/** Providers a customer may bring their own key for. */
|
|
1758
1842
|
export const AiUsageByokProviderSchema = z.enum(["anthropic", "openai"]);
|
|
@@ -1770,6 +1854,7 @@ export const SetHostingAiUsageRequestSchema = z.strictObject({
|
|
|
1770
1854
|
mode: AiPaymentModeSchema,
|
|
1771
1855
|
provider: AiUsageByokProviderSchema.optional(),
|
|
1772
1856
|
apiKey: z.string().min(1).optional(),
|
|
1857
|
+
reuseExistingKey: z.boolean().optional(),
|
|
1773
1858
|
// https only: this value is written into a published site's prod env as
|
|
1774
1859
|
// `OPENAI_BASE_URL`, so an `http://` endpoint would send the customer's
|
|
1775
1860
|
// provider key and every prompt in plaintext from the deployed site.
|
|
@@ -1789,6 +1874,14 @@ export const SetHostingAiUsageResponseSchema = z.object({
|
|
|
1789
1874
|
* mode), which is exactly the case where no redeploy is needed.
|
|
1790
1875
|
*/
|
|
1791
1876
|
configUpdatedAt: z.number().optional(),
|
|
1877
|
+
/**
|
|
1878
|
+
* The `AI_USAGE_MANAGED_PROD_ENV_KEYS` present in prod env after the write.
|
|
1879
|
+
* The client cannot derive this: its project model is deliberately not updated
|
|
1880
|
+
* with the rewrite, so projecting it locally goes stale the moment two writes
|
|
1881
|
+
* or an out-of-band env edit interleave. Optional so a client can still talk to
|
|
1882
|
+
* an API that predates it.
|
|
1883
|
+
*/
|
|
1884
|
+
managedProdEnvKeys: z.array(z.string()).optional(),
|
|
1792
1885
|
});
|
|
1793
1886
|
/** Body for `POST /projects/hosting/ai-usage/revoke`. */
|
|
1794
1887
|
export const RevokeHostingAiTokenRequestSchema = z.strictObject({
|
|
@@ -2120,17 +2213,58 @@ export const ProjectTemplateOverridesSchema = z.object({
|
|
|
2120
2213
|
settings: ProjectSettingsExternalSchema.partial().optional(),
|
|
2121
2214
|
hosting: ProjectHostingExternalSchema.optional(),
|
|
2122
2215
|
});
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2216
|
+
/** Mirrors `ProjectSourceSchema`'s repo/template split for project creation. */
|
|
2217
|
+
export const CreateTemplateSourceSchema = z.discriminatedUnion("kind", [
|
|
2218
|
+
z.object({
|
|
2219
|
+
kind: z.literal("project"),
|
|
2220
|
+
sourceProjectId: z.string().min(1).meta({
|
|
2221
|
+
description: "Project whose settings, repo fields, and hosting config seed the template.",
|
|
2222
|
+
}),
|
|
2223
|
+
sourceBranchName: z.string().min(1).meta({
|
|
2224
|
+
description: "Branch of the source project that projects created from this template are seeded from.",
|
|
2225
|
+
}),
|
|
2129
2226
|
}),
|
|
2130
|
-
|
|
2131
|
-
|
|
2227
|
+
z.object({
|
|
2228
|
+
kind: z.literal("template"),
|
|
2229
|
+
templateId: z.string().min(1).meta({
|
|
2230
|
+
description: "Built-in stub or custom template id whose settings, repo fields, and hosting config seed the new template.",
|
|
2231
|
+
}),
|
|
2132
2232
|
}),
|
|
2233
|
+
]);
|
|
2234
|
+
/**
|
|
2235
|
+
* Deprecation-window shim for callers still sending the old flat
|
|
2236
|
+
* `{ sourceProjectId, sourceBranchName }` shape — safe to delete once no
|
|
2237
|
+
* caller sends it anymore.
|
|
2238
|
+
*/
|
|
2239
|
+
const LegacyFlatTemplateSourceSchema = z.object({
|
|
2240
|
+
sourceProjectId: z.string().min(1),
|
|
2241
|
+
sourceBranchName: z.string().min(1),
|
|
2133
2242
|
});
|
|
2243
|
+
export const CreateProjectTemplateFromProjectOptionsSchema = z
|
|
2244
|
+
.union([
|
|
2245
|
+
z.object({
|
|
2246
|
+
source: CreateTemplateSourceSchema.meta({
|
|
2247
|
+
description: "The project or template whose settings, repo fields, and hosting config seed the new template.",
|
|
2248
|
+
}),
|
|
2249
|
+
overrides: ProjectTemplateOverridesSchema.optional().meta({
|
|
2250
|
+
description: "Fields to override on top of the values copied from the source.",
|
|
2251
|
+
}),
|
|
2252
|
+
}),
|
|
2253
|
+
z.object({
|
|
2254
|
+
...LegacyFlatTemplateSourceSchema.shape,
|
|
2255
|
+
overrides: ProjectTemplateOverridesSchema.optional(),
|
|
2256
|
+
}),
|
|
2257
|
+
])
|
|
2258
|
+
.transform((parsed) => "source" in parsed
|
|
2259
|
+
? parsed
|
|
2260
|
+
: {
|
|
2261
|
+
source: {
|
|
2262
|
+
kind: "project",
|
|
2263
|
+
sourceProjectId: parsed.sourceProjectId,
|
|
2264
|
+
sourceBranchName: parsed.sourceBranchName,
|
|
2265
|
+
},
|
|
2266
|
+
overrides: parsed.overrides,
|
|
2267
|
+
});
|
|
2134
2268
|
/**
|
|
2135
2269
|
* Deliberately minimal: the stored template carries plaintext secret env values,
|
|
2136
2270
|
* so nothing beyond the identity of the new template goes back to the caller.
|
package/src/projects.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { AGENT_NATIVE_STARTER_REPO, getAgentNativeRootPackageJsonWriteError, getManagedDatabasePackageJsonError, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, ProjectSettingsExternalSchema, ProjectSettingsSchema, ProjectTemplateOverridesSchema, ShapeSessionSchema, } from "./projects";
|
|
2
|
+
import { AGENT_NATIVE_STARTER_REPO, getAgentNativeRootPackageJsonWriteError, getManagedDatabasePackageJsonError, getProjectState, GetShapeQuestionnaireOptionsSchema, InitialPromptSchema, isProjectDeleted, matchesAgentNativeStarter, ProjectHostingExternalSchema, ProjectHostingSchema, ProjectSettingsExternalSchema, ProjectSettingsSchema, ProjectTemplateOverridesSchema, ShapeSessionSchema, SubmitShapeAnswersOptionsSchema, } from "./projects";
|
|
3
3
|
describe("project hosting schemas", () => {
|
|
4
4
|
it("accepts the canonical published branch route", () => {
|
|
5
5
|
expect(ProjectHostingSchema.parse({ publishedBranchId: "branch-live" })).toEqual({ publishedBranchId: "branch-live" });
|
|
@@ -42,6 +42,16 @@ describe("guided onboarding project settings", () => {
|
|
|
42
42
|
},
|
|
43
43
|
],
|
|
44
44
|
initialPromptId: "prompt-1",
|
|
45
|
+
issuedAt: "2026-09-09T12:00:00.000Z",
|
|
46
|
+
decisions: [
|
|
47
|
+
{
|
|
48
|
+
questionId: "authentication",
|
|
49
|
+
ask: false,
|
|
50
|
+
llmOptionId: "required",
|
|
51
|
+
confidence: 0.99,
|
|
52
|
+
guessOptionId: "required",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
45
55
|
};
|
|
46
56
|
it("parses a snapshotted questionnaire session", () => {
|
|
47
57
|
expect(ShapeSessionSchema.parse(shapeSession)).toEqual(shapeSession);
|
|
@@ -55,10 +65,56 @@ describe("guided onboarding project settings", () => {
|
|
|
55
65
|
catalogVersion: "v1",
|
|
56
66
|
})).toThrow();
|
|
57
67
|
});
|
|
68
|
+
it("parses a project-level initial prompt", () => {
|
|
69
|
+
const initialPrompt = {
|
|
70
|
+
id: "prompt-1",
|
|
71
|
+
projectId: "project-1",
|
|
72
|
+
prompt: "Build an expense tracker",
|
|
73
|
+
createdBy: "user-1",
|
|
74
|
+
createdAt: 1788952800000,
|
|
75
|
+
};
|
|
76
|
+
expect(InitialPromptSchema.parse(initialPrompt)).toEqual(initialPrompt);
|
|
77
|
+
});
|
|
58
78
|
it("does not allow clients to write a shape session", () => {
|
|
59
79
|
expect(ProjectSettingsExternalSchema.parse({ shapeSession })).toEqual({});
|
|
60
80
|
expect(ProjectTemplateOverridesSchema.parse({ settings: { shapeSession } })).toEqual({ settings: {} });
|
|
61
81
|
});
|
|
82
|
+
it("parses questionnaire endpoint inputs without accepting server fields", () => {
|
|
83
|
+
expect(GetShapeQuestionnaireOptionsSchema.parse({ projectId: "project-1" })).toEqual({ projectId: "project-1" });
|
|
84
|
+
expect(SubmitShapeAnswersOptionsSchema.parse({
|
|
85
|
+
projectId: "project-1",
|
|
86
|
+
questionnaireId: "questionnaire-1",
|
|
87
|
+
answers: [
|
|
88
|
+
{
|
|
89
|
+
questionId: "authentication",
|
|
90
|
+
optionId: "required",
|
|
91
|
+
skipped: false,
|
|
92
|
+
delegated: false,
|
|
93
|
+
resolvedFrom: "llm",
|
|
94
|
+
llmOptionId: "not-required",
|
|
95
|
+
guessOptionId: "not-required",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
})).toEqual({
|
|
99
|
+
projectId: "project-1",
|
|
100
|
+
questionnaireId: "questionnaire-1",
|
|
101
|
+
answers: [
|
|
102
|
+
{
|
|
103
|
+
questionId: "authentication",
|
|
104
|
+
optionId: "required",
|
|
105
|
+
skipped: false,
|
|
106
|
+
delegated: false,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
it("requires non-empty questionnaire ids and at least one answer", () => {
|
|
112
|
+
expect(() => SubmitShapeAnswersOptionsSchema.parse({
|
|
113
|
+
projectId: "",
|
|
114
|
+
questionnaireId: "",
|
|
115
|
+
answers: [],
|
|
116
|
+
})).toThrow();
|
|
117
|
+
});
|
|
62
118
|
});
|
|
63
119
|
describe("matchesAgentNativeStarter", () => {
|
|
64
120
|
it("matches when repoName is the starter", () => {
|
|
@@ -136,3 +192,22 @@ describe("getAgentNativeRootPackageJsonWriteError", () => {
|
|
|
136
192
|
})).toBeUndefined();
|
|
137
193
|
});
|
|
138
194
|
});
|
|
195
|
+
describe("getProjectState", () => {
|
|
196
|
+
const project = (fields) => fields;
|
|
197
|
+
it("prefers the state field", () => {
|
|
198
|
+
expect(getProjectState(project({ state: "archived" }))).toBe("archived");
|
|
199
|
+
expect(isProjectDeleted(project({ state: "deleted" }))).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
it("falls back to the legacy deleted field", () => {
|
|
202
|
+
expect(getProjectState(project({ deleted: true }))).toBe("deleted");
|
|
203
|
+
expect(isProjectDeleted(project({ deleted: true }))).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
/** A restored project keeps `deleted: true` but gets an explicit state. */
|
|
206
|
+
it("lets an explicit state win over the legacy field", () => {
|
|
207
|
+
expect(isProjectDeleted(project({ state: "active", deleted: true }))).toBe(false);
|
|
208
|
+
});
|
|
209
|
+
it("defaults to active", () => {
|
|
210
|
+
expect(getProjectState(project({}))).toBe("active");
|
|
211
|
+
expect(isProjectDeleted(project({ deleted: false }))).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
});
|
package/src/publish-agent.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { GenerateCompletionStep } from "./codegen.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* Client-safe metadata for a Publish Agent skill: enough for a picker UI
|
|
5
|
+
* (id, name, description), without the instruction `content` sent to the
|
|
6
|
+
* model. `id` is the shared key the server uses to attach that content —
|
|
7
|
+
* see `PUBLISH_AGENT_SKILLS` in `packages/service/publish-agent/config.ts`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PublishAgentSkillInfoSchema: z.ZodObject<{
|
|
10
|
+
id: z.ZodString;
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
description: z.ZodString;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type PublishAgentSkillInfo = z.infer<typeof PublishAgentSkillInfoSchema>;
|
|
15
|
+
export declare const PUBLISH_AGENT_SKILLS_INFO: readonly PublishAgentSkillInfo[];
|
|
3
16
|
export declare const PublishAgentSessionCursorSchema: z.ZodObject<{
|
|
4
17
|
updatedAt: z.ZodNumber;
|
|
5
18
|
id: z.ZodString;
|
package/src/publish-agent.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Client-safe metadata for a Publish Agent skill: enough for a picker UI
|
|
4
|
+
* (id, name, description), without the instruction `content` sent to the
|
|
5
|
+
* model. `id` is the shared key the server uses to attach that content —
|
|
6
|
+
* see `PUBLISH_AGENT_SKILLS` in `packages/service/publish-agent/config.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export const PublishAgentSkillInfoSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
description: z.string(),
|
|
13
|
+
})
|
|
14
|
+
.meta({ title: "PublishAgentSkillInfo" });
|
|
15
|
+
export const PUBLISH_AGENT_SKILLS_INFO = [
|
|
16
|
+
{
|
|
17
|
+
id: "publish-agent-skill-create-page",
|
|
18
|
+
name: "create-page",
|
|
19
|
+
description: "Create a new page in the Builder CMS space. Use when the user asks to create, add, or scaffold a new page.",
|
|
20
|
+
},
|
|
21
|
+
];
|
|
2
22
|
export const PublishAgentSessionCursorSchema = z
|
|
3
23
|
.object({
|
|
4
24
|
updatedAt: z.number().int(),
|
package/src/realtime.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const BUILDER_REALTIME_MODEL: "gpt-
|
|
2
|
+
export declare const BUILDER_REALTIME_MODEL: "gpt-live-1";
|
|
3
|
+
export declare const BUILDER_REALTIME_LEGACY_MODEL: "gpt-realtime-2.1";
|
|
4
|
+
export declare const BUILDER_REALTIME_DELEGATED_MODEL: "gpt-5.6-luna";
|
|
3
5
|
export declare const BUILDER_REALTIME_MAX_SDP_LENGTH = 256000;
|
|
4
6
|
export declare const BUILDER_REALTIME_MAX_SESSION_BYTES = 64000;
|
|
5
7
|
export declare const OpenAIRealtimeFunctionToolSchema: z.ZodObject<{
|
|
@@ -137,9 +139,122 @@ export declare const OpenAIRealtimeSessionConfigSchema: z.ZodObject<{
|
|
|
137
139
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
138
140
|
}, z.core.$strip>;
|
|
139
141
|
export type OpenAIRealtimeSessionConfig = z.infer<typeof OpenAIRealtimeSessionConfigSchema>;
|
|
142
|
+
/** The subset of GPT-Live session configuration accepted by Builder Connect. */
|
|
143
|
+
export declare const OpenAILiveSessionConfigSchema: z.ZodObject<{
|
|
144
|
+
model: z.ZodLiteral<"gpt-live-1">;
|
|
145
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
146
|
+
audio: z.ZodOptional<z.ZodObject<{
|
|
147
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
148
|
+
voice: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
149
|
+
id: z.ZodString;
|
|
150
|
+
}, z.core.$strip>]>>;
|
|
151
|
+
}, z.core.$strip>>;
|
|
152
|
+
}, z.core.$strip>>;
|
|
153
|
+
delegation: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
|
|
154
|
+
type: z.ZodLiteral<"responses">;
|
|
155
|
+
responses: z.ZodObject<{
|
|
156
|
+
model: z.ZodLiteral<"gpt-5.6-luna">;
|
|
157
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
158
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
159
|
+
type: z.ZodLiteral<"function">;
|
|
160
|
+
name: z.ZodString;
|
|
161
|
+
description: z.ZodOptional<z.ZodString>;
|
|
162
|
+
parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
163
|
+
strict: z.ZodOptional<z.ZodBoolean>;
|
|
164
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
165
|
+
type: z.ZodLiteral<"web_search">;
|
|
166
|
+
}, z.core.$strip>]>>>;
|
|
167
|
+
tool_choice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
168
|
+
auto: "auto";
|
|
169
|
+
none: "none";
|
|
170
|
+
required: "required";
|
|
171
|
+
}>, z.ZodObject<{
|
|
172
|
+
type: z.ZodLiteral<"function">;
|
|
173
|
+
name: z.ZodString;
|
|
174
|
+
}, z.core.$strip>]>>;
|
|
175
|
+
parallel_tool_calls: z.ZodOptional<z.ZodBoolean>;
|
|
176
|
+
max_output_tokens: z.ZodOptional<z.ZodNumber>;
|
|
177
|
+
service_tier: z.ZodOptional<z.ZodEnum<{
|
|
178
|
+
auto: "auto";
|
|
179
|
+
default: "default";
|
|
180
|
+
priority: "priority";
|
|
181
|
+
}>>;
|
|
182
|
+
reasoning: z.ZodOptional<z.ZodObject<{
|
|
183
|
+
effort: z.ZodEnum<{
|
|
184
|
+
high: "high";
|
|
185
|
+
low: "low";
|
|
186
|
+
max: "max";
|
|
187
|
+
medium: "medium";
|
|
188
|
+
minimal: "minimal";
|
|
189
|
+
none: "none";
|
|
190
|
+
xhigh: "xhigh";
|
|
191
|
+
}>;
|
|
192
|
+
}, z.core.$strip>>;
|
|
193
|
+
}, z.core.$strip>;
|
|
194
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
195
|
+
type: z.ZodLiteral<"client">;
|
|
196
|
+
}, z.core.$strip>]>>>;
|
|
197
|
+
store: z.ZodOptional<z.ZodBoolean>;
|
|
198
|
+
}, z.core.$strip>;
|
|
199
|
+
export type OpenAILiveSessionConfig = z.infer<typeof OpenAILiveSessionConfigSchema>;
|
|
140
200
|
export declare const BuilderRealtimeSessionRequestSchema: z.ZodObject<{
|
|
141
201
|
sdp: z.ZodString;
|
|
142
|
-
session: z.ZodObject<{
|
|
202
|
+
session: z.ZodUnion<readonly [z.ZodObject<{
|
|
203
|
+
model: z.ZodLiteral<"gpt-live-1">;
|
|
204
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
205
|
+
audio: z.ZodOptional<z.ZodObject<{
|
|
206
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
207
|
+
voice: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
208
|
+
id: z.ZodString;
|
|
209
|
+
}, z.core.$strip>]>>;
|
|
210
|
+
}, z.core.$strip>>;
|
|
211
|
+
}, z.core.$strip>>;
|
|
212
|
+
delegation: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
|
|
213
|
+
type: z.ZodLiteral<"responses">;
|
|
214
|
+
responses: z.ZodObject<{
|
|
215
|
+
model: z.ZodLiteral<"gpt-5.6-luna">;
|
|
216
|
+
instructions: z.ZodOptional<z.ZodString>;
|
|
217
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
218
|
+
type: z.ZodLiteral<"function">;
|
|
219
|
+
name: z.ZodString;
|
|
220
|
+
description: z.ZodOptional<z.ZodString>;
|
|
221
|
+
parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
222
|
+
strict: z.ZodOptional<z.ZodBoolean>;
|
|
223
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
224
|
+
type: z.ZodLiteral<"web_search">;
|
|
225
|
+
}, z.core.$strip>]>>>;
|
|
226
|
+
tool_choice: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
227
|
+
auto: "auto";
|
|
228
|
+
none: "none";
|
|
229
|
+
required: "required";
|
|
230
|
+
}>, z.ZodObject<{
|
|
231
|
+
type: z.ZodLiteral<"function">;
|
|
232
|
+
name: z.ZodString;
|
|
233
|
+
}, z.core.$strip>]>>;
|
|
234
|
+
parallel_tool_calls: z.ZodOptional<z.ZodBoolean>;
|
|
235
|
+
max_output_tokens: z.ZodOptional<z.ZodNumber>;
|
|
236
|
+
service_tier: z.ZodOptional<z.ZodEnum<{
|
|
237
|
+
auto: "auto";
|
|
238
|
+
default: "default";
|
|
239
|
+
priority: "priority";
|
|
240
|
+
}>>;
|
|
241
|
+
reasoning: z.ZodOptional<z.ZodObject<{
|
|
242
|
+
effort: z.ZodEnum<{
|
|
243
|
+
high: "high";
|
|
244
|
+
low: "low";
|
|
245
|
+
max: "max";
|
|
246
|
+
medium: "medium";
|
|
247
|
+
minimal: "minimal";
|
|
248
|
+
none: "none";
|
|
249
|
+
xhigh: "xhigh";
|
|
250
|
+
}>;
|
|
251
|
+
}, z.core.$strip>>;
|
|
252
|
+
}, z.core.$strip>;
|
|
253
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
254
|
+
type: z.ZodLiteral<"client">;
|
|
255
|
+
}, z.core.$strip>]>>>;
|
|
256
|
+
store: z.ZodOptional<z.ZodBoolean>;
|
|
257
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
143
258
|
type: z.ZodLiteral<"realtime">;
|
|
144
259
|
model: z.ZodLiteral<"gpt-realtime-2.1">;
|
|
145
260
|
output_modalities: z.ZodTuple<[z.ZodLiteral<"audio">], null>;
|
|
@@ -227,6 +342,6 @@ export declare const BuilderRealtimeSessionRequestSchema: z.ZodObject<{
|
|
|
227
342
|
disabled: "disabled";
|
|
228
343
|
}>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
229
344
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
230
|
-
}, z.core.$strip>;
|
|
345
|
+
}, z.core.$strip>]>;
|
|
231
346
|
}, z.core.$strip>;
|
|
232
347
|
export type BuilderRealtimeSessionRequest = z.infer<typeof BuilderRealtimeSessionRequestSchema>;
|
package/src/realtime.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export const BUILDER_REALTIME_MODEL = "gpt-
|
|
2
|
+
export const BUILDER_REALTIME_MODEL = "gpt-live-1";
|
|
3
|
+
export const BUILDER_REALTIME_LEGACY_MODEL = "gpt-realtime-2.1";
|
|
4
|
+
export const BUILDER_REALTIME_DELEGATED_MODEL = "gpt-5.6-luna";
|
|
3
5
|
export const BUILDER_REALTIME_MAX_SDP_LENGTH = 256000;
|
|
4
6
|
export const BUILDER_REALTIME_MAX_SESSION_BYTES = 64000;
|
|
5
7
|
const utf8ByteLength = (value) => new TextEncoder().encode(value).length;
|
|
@@ -109,7 +111,7 @@ const OpenAIRealtimeToolChoiceSchema = z.union([
|
|
|
109
111
|
export const OpenAIRealtimeSessionConfigSchema = z
|
|
110
112
|
.object({
|
|
111
113
|
type: z.literal("realtime"),
|
|
112
|
-
model: z.literal(
|
|
114
|
+
model: z.literal(BUILDER_REALTIME_LEGACY_MODEL),
|
|
113
115
|
output_modalities: z.tuple([z.literal("audio")]),
|
|
114
116
|
instructions: z.string().max(32000).optional(),
|
|
115
117
|
audio: z
|
|
@@ -148,11 +150,76 @@ export const OpenAIRealtimeSessionConfigSchema = z
|
|
|
148
150
|
})
|
|
149
151
|
.refine((session) => utf8ByteLength(JSON.stringify(session)) <=
|
|
150
152
|
BUILDER_REALTIME_MAX_SESSION_BYTES, { message: "Realtime session configuration is too large" });
|
|
153
|
+
const OpenAILiveToolSchema = z.union([
|
|
154
|
+
OpenAIRealtimeFunctionToolSchema,
|
|
155
|
+
z.object({ type: z.literal("web_search") }),
|
|
156
|
+
]);
|
|
157
|
+
const OpenAILiveResponsesDelegationSchema = z.object({
|
|
158
|
+
model: z.literal(BUILDER_REALTIME_DELEGATED_MODEL),
|
|
159
|
+
instructions: z.string().max(32000).optional(),
|
|
160
|
+
tools: z.array(OpenAILiveToolSchema).max(32).optional(),
|
|
161
|
+
tool_choice: z
|
|
162
|
+
.union([
|
|
163
|
+
z.enum(["auto", "none", "required"]),
|
|
164
|
+
z.object({
|
|
165
|
+
type: z.literal("function"),
|
|
166
|
+
name: z.string().min(1).max(64),
|
|
167
|
+
}),
|
|
168
|
+
])
|
|
169
|
+
.optional(),
|
|
170
|
+
parallel_tool_calls: z.boolean().optional(),
|
|
171
|
+
max_output_tokens: z.number().int().min(16).max(4096).optional(),
|
|
172
|
+
service_tier: z.enum(["auto", "default", "priority"]).optional(),
|
|
173
|
+
reasoning: z
|
|
174
|
+
.object({
|
|
175
|
+
effort: z.enum([
|
|
176
|
+
"none",
|
|
177
|
+
"minimal",
|
|
178
|
+
"low",
|
|
179
|
+
"medium",
|
|
180
|
+
"high",
|
|
181
|
+
"xhigh",
|
|
182
|
+
"max",
|
|
183
|
+
]),
|
|
184
|
+
})
|
|
185
|
+
.optional(),
|
|
186
|
+
});
|
|
187
|
+
const OpenAILiveDelegationSchema = z.union([
|
|
188
|
+
z.object({
|
|
189
|
+
type: z.literal("responses"),
|
|
190
|
+
responses: OpenAILiveResponsesDelegationSchema,
|
|
191
|
+
}),
|
|
192
|
+
z.object({ type: z.literal("client") }),
|
|
193
|
+
]);
|
|
194
|
+
const OpenAILiveOutputAudioSchema = z.object({
|
|
195
|
+
voice: z
|
|
196
|
+
.union([
|
|
197
|
+
z.string().min(1).max(128),
|
|
198
|
+
z.object({ id: z.string().min(1).max(256) }),
|
|
199
|
+
])
|
|
200
|
+
.optional(),
|
|
201
|
+
});
|
|
202
|
+
/** The subset of GPT-Live session configuration accepted by Builder Connect. */
|
|
203
|
+
export const OpenAILiveSessionConfigSchema = z
|
|
204
|
+
.object({
|
|
205
|
+
model: z.literal(BUILDER_REALTIME_MODEL),
|
|
206
|
+
instructions: z.string().max(32000).optional(),
|
|
207
|
+
audio: z
|
|
208
|
+
.object({ output: OpenAILiveOutputAudioSchema.optional() })
|
|
209
|
+
.optional(),
|
|
210
|
+
delegation: OpenAILiveDelegationSchema.nullable().optional(),
|
|
211
|
+
store: z.boolean().optional(),
|
|
212
|
+
})
|
|
213
|
+
.refine((session) => utf8ByteLength(JSON.stringify(session)) <=
|
|
214
|
+
BUILDER_REALTIME_MAX_SESSION_BYTES, { message: "Live session configuration is too large" });
|
|
151
215
|
export const BuilderRealtimeSessionRequestSchema = z.object({
|
|
152
216
|
sdp: z
|
|
153
217
|
.string()
|
|
154
218
|
.min(1)
|
|
155
219
|
.max(BUILDER_REALTIME_MAX_SDP_LENGTH)
|
|
156
220
|
.refine((sdp) => sdp.trim().length > 0, { message: "SDP cannot be blank" }),
|
|
157
|
-
session:
|
|
221
|
+
session: z.union([
|
|
222
|
+
OpenAILiveSessionConfigSchema,
|
|
223
|
+
OpenAIRealtimeSessionConfigSchema,
|
|
224
|
+
]),
|
|
158
225
|
});
|