@builder.io/ai-utils 0.46.0 → 0.47.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/ai-utils",
3
- "version": "0.46.0",
3
+ "version": "0.47.1",
4
4
  "description": "Builder.io AI utils",
5
5
  "files": [
6
6
  "src"
package/src/codegen.d.ts CHANGED
@@ -43,11 +43,17 @@ export interface CustomAgentInfo {
43
43
  }
44
44
  /** Per-agent model overrides. String = fixed model, string[] = round-robin. */
45
45
  export type AgentModelOverrides = Record<string, string | string[]>;
46
- export type ReviewEffort = "medium" | "high";
46
+ export type ReviewEffort = "medium" | "high" | "low";
47
47
  export interface CustomAgentDefinition {
48
48
  name: string;
49
49
  description?: string;
50
- systemPrompt?: string;
50
+ /**
51
+ * When provided as an array, the first element must be the static prompt and
52
+ * subsequent elements should be dynamic content (e.g. env var placeholders).
53
+ * Only the first element is marked as cacheable — placing dynamic content
54
+ * first would invalidate the prompt cache on every request.
55
+ */
56
+ systemPrompt?: string | string[];
51
57
  tools?: string[];
52
58
  model?: string;
53
59
  roundRobinModels?: string[];
@@ -416,7 +422,7 @@ export interface UpdateSetupValueToolInput {
416
422
  };
417
423
  reason: string;
418
424
  }
419
- export type ExitState = "verified" | "no-frontend" | "empty-project" | "mobile-project" | "user-question" | "other" | "started";
425
+ export type ExitState = "verified" | "no-frontend" | "empty-project" | "mobile-project" | "user-question" | "code-change-required" | "other" | "started";
420
426
  export interface ExitToolInput {
421
427
  state: ExitState;
422
428
  summary: string;
@@ -741,13 +747,14 @@ export interface CodeGenToolMap {
741
747
  ArchiveBranch: ArchiveBranchToolInput;
742
748
  RunningAgents: RunningAgentsToolInput;
743
749
  IDEDiagnostics: IDEDiagnosticsToolInput;
750
+ PullPrototype: PullPrototypeToolInput;
744
751
  }
745
752
  export type CodeGenTools = keyof CodeGenToolMap;
746
753
  export type AllCodeGenTools = CodeGenTools | "web_search";
747
754
  export type SessionMode = "planning" | "normal" | "auto-planning" | "deep-research";
748
755
  export type CodeGenMode = "quality" | "quality-v3" | "quality-v4" | "quality-v4-agent";
749
756
  export type QueueMode = "next-turn" | "until-idle";
750
- export declare const BASE_CODEGEN_POSITIONS: readonly ["fusion", "editor-ai", "repo-indexing", "cli", "create-app-firebase", "create-app-lovable", "builder-code-panel", "setup-project", "code-review-orchestrator", "project-configuration", "org-agent", "browser-testing", "projects-scheduler-memory-extraction", "unknown", "dsi-mcp"];
757
+ export declare const BASE_CODEGEN_POSITIONS: readonly ["fusion", "editor-ai", "repo-indexing", "cli", "create-app-firebase", "create-app-lovable", "builder-code-panel", "setup-project", "code-review-orchestrator", "project-configuration", "org-agent", "browser-testing", "projects-scheduler-memory-extraction", "builder-code", "unknown", "dsi-mcp"];
751
758
  export type BaseCodeGenPosition = (typeof BASE_CODEGEN_POSITIONS)[number];
752
759
  export type CodeGenPosition = BaseCodeGenPosition | `${BaseCodeGenPosition}-agent`;
753
760
  export interface RepoIndexingConfig {
@@ -771,7 +778,7 @@ export interface CodeGenInputOptions {
771
778
  planningPrompt?: boolean;
772
779
  customInstructions?: CustomInstruction[];
773
780
  customAgents?: CustomAgentInfo[];
774
- systemPromptOverride?: string;
781
+ systemPromptOverride?: string | string[];
775
782
  userPrompt?: string;
776
783
  systemReminders?: SystemReminder[];
777
784
  ephemeralUserPrompt?: string;
@@ -1290,6 +1297,12 @@ export interface DiagnosticEntry {
1290
1297
  export interface IDEDiagnosticsToolInput {
1291
1298
  file_path?: string;
1292
1299
  }
1300
+ export interface PullPrototypeToolInput {
1301
+ url: string;
1302
+ project_id?: string;
1303
+ branch_name?: string;
1304
+ space_id?: string;
1305
+ }
1293
1306
  export interface DiagnosticsResponse {
1294
1307
  ideName: string;
1295
1308
  diagnostics: DiagnosticEntry[];
@@ -1565,6 +1578,7 @@ export interface GenerateCodeEventMCPStatus {
1565
1578
  export interface MCPAuthRequiredServer {
1566
1579
  serverId: string;
1567
1580
  name: string;
1581
+ normalizedServerName: string;
1568
1582
  url: string;
1569
1583
  authorizationUrl: string;
1570
1584
  scopes: string[];
package/src/codegen.js CHANGED
@@ -12,6 +12,7 @@ export const BASE_CODEGEN_POSITIONS = [
12
12
  "org-agent",
13
13
  "browser-testing",
14
14
  "projects-scheduler-memory-extraction",
15
+ "builder-code",
15
16
  "unknown",
16
17
  "dsi-mcp",
17
18
  ];
@@ -1,4 +1,4 @@
1
- import { resolveTarget, extractHostname, extractPort } from "./targets.js";
1
+ import { resolveTarget, extractHostname, extractPort, extractExplicitPort, } from "./targets.js";
2
2
  import { getCheckTypeForTestId, isCheckAvailable, getUnavailabilityReason, } from "./environment.js";
3
3
  import { httpCheck } from "./checks/http-check.js";
4
4
  import { dnsCheck } from "./checks/dns-check.js";
@@ -106,7 +106,7 @@ async function runSingleCheck(test, gitHost, fetchFn, dispatcher, connectFn) {
106
106
  case "ssh":
107
107
  return sshCheck({
108
108
  hostname: extractHostname(target),
109
- port: 22,
109
+ port: extractExplicitPort(target, 22),
110
110
  source,
111
111
  testId,
112
112
  });
@@ -3,4 +3,13 @@ export declare const BUILDER_TARGETS: Record<string, string>;
3
3
  export declare const DEFAULT_PORTS: Record<string, number>;
4
4
  export declare function resolveTarget(testId: TestId, gitHost?: string): string;
5
5
  export declare function extractHostname(target: string): string;
6
+ /**
7
+ * Extract only an explicitly specified port from a URL, ignoring protocol-specific defaults.
8
+ * Returns defaultPort when no port is present in the URL string.
9
+ */
10
+ export declare function extractExplicitPort(target: string, defaultPort: number): number;
11
+ /**
12
+ * Extract port from a URL, with protocol-aware defaults.
13
+ * Returns 80 for http:// URLs without an explicit port, otherwise falls back to defaultPort.
14
+ */
6
15
  export declare function extractPort(target: string, defaultPort?: number): number;
@@ -36,14 +36,22 @@ export function extractHostname(target) {
36
36
  return target;
37
37
  }
38
38
  }
39
- export function extractPort(target, defaultPort = 443) {
39
+ /**
40
+ * Extract only an explicitly specified port from a URL, ignoring protocol-specific defaults.
41
+ * Returns defaultPort when no port is present in the URL string.
42
+ */
43
+ export function extractExplicitPort(target, defaultPort) {
40
44
  try {
41
45
  const url = new URL(target);
42
46
  if (url.port) {
43
47
  return parseInt(url.port, 10);
44
48
  }
45
- if (url.protocol === "http:") {
46
- return 80;
49
+ // URL API strips scheme-default ports (:443 for https, :80 for http).
50
+ // Check the authority portion only to avoid false positives from paths/query strings.
51
+ const schemeDefault = url.protocol === "https:" ? 443 : url.protocol === "http:" ? 80 : null;
52
+ const authority = target.slice(target.indexOf("://") + 3).split(/[/?#]/)[0];
53
+ if (schemeDefault !== null && authority.endsWith(`:${schemeDefault}`)) {
54
+ return schemeDefault;
47
55
  }
48
56
  return defaultPort;
49
57
  }
@@ -51,3 +59,19 @@ export function extractPort(target, defaultPort = 443) {
51
59
  return defaultPort;
52
60
  }
53
61
  }
62
+ /**
63
+ * Extract port from a URL, with protocol-aware defaults.
64
+ * Returns 80 for http:// URLs without an explicit port, otherwise falls back to defaultPort.
65
+ */
66
+ export function extractPort(target, defaultPort = 443) {
67
+ try {
68
+ const url = new URL(target);
69
+ if (url.protocol === "http:" && !url.port) {
70
+ return 80;
71
+ }
72
+ }
73
+ catch (_a) {
74
+ // fall through
75
+ }
76
+ return extractExplicitPort(target, defaultPort);
77
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { extractPort, extractExplicitPort } from "./targets";
3
+ describe("extractPort", () => {
4
+ it("returns explicit port from URL", () => {
5
+ expect(extractPort("https://git.amazon.com:2222", 443)).toBe(2222);
6
+ });
7
+ it("returns 80 for http:// URLs without explicit port", () => {
8
+ expect(extractPort("http://git.example.com", 443)).toBe(80);
9
+ });
10
+ it("returns default port for https:// URLs without explicit port", () => {
11
+ expect(extractPort("https://github.com", 443)).toBe(443);
12
+ });
13
+ it("returns default port for invalid URLs", () => {
14
+ expect(extractPort("not-a-url", 443)).toBe(443);
15
+ });
16
+ });
17
+ describe("extractExplicitPort", () => {
18
+ it("returns explicit port from URL", () => {
19
+ expect(extractExplicitPort("https://git.amazon.com:2222", 22)).toBe(2222);
20
+ });
21
+ it("returns default for https:// URL without explicit port", () => {
22
+ expect(extractExplicitPort("https://github.com", 22)).toBe(22);
23
+ });
24
+ it("returns default for http:// URL without explicit port (does NOT return 80)", () => {
25
+ expect(extractExplicitPort("http://git.example.com", 22)).toBe(22);
26
+ });
27
+ it("returns 443 when https URL explicitly specifies :443", () => {
28
+ expect(extractExplicitPort("https://host:443", 22)).toBe(443);
29
+ expect(extractExplicitPort("https://host:443/path", 22)).toBe(443);
30
+ });
31
+ it("returns 80 when http URL explicitly specifies :80", () => {
32
+ expect(extractExplicitPort("http://host:80", 22)).toBe(80);
33
+ expect(extractExplicitPort("http://host:80/path", 22)).toBe(80);
34
+ });
35
+ it("ignores scheme-default port in path or query string", () => {
36
+ expect(extractExplicitPort("https://host/path?next=host:443", 22)).toBe(22);
37
+ expect(extractExplicitPort("https://host/host:443", 22)).toBe(22);
38
+ });
39
+ it("detects explicit :443 with userinfo in URL", () => {
40
+ expect(extractExplicitPort("https://user:password@host:443", 22)).toBe(443);
41
+ });
42
+ it("returns default for invalid URLs", () => {
43
+ expect(extractExplicitPort("not-a-url", 22)).toBe(22);
44
+ });
45
+ });
package/src/events.d.ts CHANGED
@@ -504,7 +504,7 @@ export type ReviewSubmittedV1 = FusionEventVariant<"review.submitted", {
504
504
  hasRecording?: boolean;
505
505
  /** Recording URL if hasRecording is true */
506
506
  recordingUrl?: string;
507
- /** Posted comments from GitHub API */
507
+ /** Posted comments from GitHub API (formatted bodies) */
508
508
  postedComments: Array<{
509
509
  id: number;
510
510
  node_id: string;
package/src/messages.d.ts CHANGED
@@ -152,7 +152,7 @@ export type ServerToolUseContentUnion = ServerToolUseContent[] | ServerToolUseCo
152
152
  export interface ContentMessageItemServerToolUse {
153
153
  type: "server_tool_use";
154
154
  id: string;
155
- name: "web_search" | "code_execution" | "web_fetch" | "bash_code_execution" | "text_editor_code_execution" | "tool_search_tool_regex" | "tool_search_tool_bm25";
155
+ name: "advisor" | "web_search" | "web_fetch" | "code_execution" | "bash_code_execution" | "text_editor_code_execution" | "tool_search_tool_regex" | "tool_search_tool_bm25";
156
156
  input: unknown;
157
157
  caller?: any;
158
158
  completion?: string;
package/src/projects.d.ts CHANGED
@@ -451,6 +451,7 @@ export interface BranchSharedData {
451
451
  isDefault?: boolean;
452
452
  friendlyName?: string;
453
453
  description?: string;
454
+ lastUsedModel?: string | null;
454
455
  useHomeDir?: boolean;
455
456
  useCloudHomeDir?: boolean;
456
457
  reviewers?: string[] | null;