@builder.io/ai-utils 0.46.0 → 0.47.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/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.0",
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;
@@ -771,7 +777,7 @@ export interface CodeGenInputOptions {
771
777
  planningPrompt?: boolean;
772
778
  customInstructions?: CustomInstruction[];
773
779
  customAgents?: CustomAgentInfo[];
774
- systemPromptOverride?: string;
780
+ systemPromptOverride?: string | string[];
775
781
  userPrompt?: string;
776
782
  systemReminders?: SystemReminder[];
777
783
  ephemeralUserPrompt?: string;
@@ -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
+ });