@builder.io/ai-utils 0.31.0 → 0.31.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/claw.d.ts +42 -0
- package/src/claw.js +61 -0
- package/src/codegen.d.ts +8 -1
- package/src/connectivity/checks/tcp-check.d.ts +3 -0
- package/src/connectivity/checks/tcp-check.js +19 -1
- package/src/connectivity/checks/tls-check.d.ts +3 -0
- package/src/connectivity/checks/tls-check.js +30 -1
- package/src/connectivity/run-checks.js +5 -3
- package/src/connectivity/types.d.ts +6 -0
- package/src/projects.d.ts +3 -14
package/package.json
CHANGED
package/src/claw.d.ts
CHANGED
|
@@ -41,5 +41,47 @@ export interface ParsedChannelId {
|
|
|
41
41
|
* "slack/thread/T01234/C56789/1234567890.123456" → { platform: "slack", type: "thread", ids: ["T01234", "C56789", "1234567890.123456"] }
|
|
42
42
|
* "jira/comment/cloud-id/PROJ-123" → { platform: "jira", type: "comment", ids: ["cloud-id", "PROJ-123"] }
|
|
43
43
|
* "builder/branch/proj-id/my-branch" → { platform: "builder", type: "branch", ids: ["proj-id", "my-branch"] }
|
|
44
|
+
* "inbox/user/builder-user-id" → { platform: "inbox", type: "user", ids: ["builder-user-id"] }
|
|
44
45
|
*/
|
|
45
46
|
export declare function parseChannelId(channelId: string): ParsedChannelId;
|
|
47
|
+
export interface WorkerReportOptions {
|
|
48
|
+
/** The original user's channel that triggered this work. */
|
|
49
|
+
originChannelId?: string;
|
|
50
|
+
/** The report content. */
|
|
51
|
+
content: string;
|
|
52
|
+
/** Project ID (for branch reports). */
|
|
53
|
+
projectId?: string;
|
|
54
|
+
/** Branch name (for branch reports). */
|
|
55
|
+
branchName?: string;
|
|
56
|
+
/** Agent/tool ID (for sub-agent reports). */
|
|
57
|
+
agentId?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Formats a `<worker_report>` message for the org-agent.
|
|
61
|
+
*
|
|
62
|
+
* Used when a spawned branch or sub-agent reports its results back.
|
|
63
|
+
* The org-agent uses `<origin_channel_id>` to route the response to the
|
|
64
|
+
* correct user channel.
|
|
65
|
+
*/
|
|
66
|
+
export declare function formatWorkerReport(opts: WorkerReportOptions): string;
|
|
67
|
+
export interface IncomingMessageOptions {
|
|
68
|
+
/** The source channel (e.g. slack/thread/TEAM/CHANNEL/TS). */
|
|
69
|
+
channelId: string;
|
|
70
|
+
/** DM channel ID, if the message was a direct message. */
|
|
71
|
+
dmId?: string;
|
|
72
|
+
/** Display name of the sender. */
|
|
73
|
+
sender?: string;
|
|
74
|
+
/** Pre-formatted timestamp string. */
|
|
75
|
+
timestamp: string;
|
|
76
|
+
/** The message body. */
|
|
77
|
+
content: string;
|
|
78
|
+
/** Optional context to prepend (e.g. Slack thread history). */
|
|
79
|
+
messageContext?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Formats an `<incoming_message>` for the org-agent.
|
|
83
|
+
*
|
|
84
|
+
* Used when a real user message arrives from an integration.
|
|
85
|
+
* The org-agent uses `<channel_id>` to reply in the same medium.
|
|
86
|
+
*/
|
|
87
|
+
export declare function formatIncomingMessage(opts: IncomingMessageOptions): string;
|
package/src/claw.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* "slack/thread/T01234/C56789/1234567890.123456" → { platform: "slack", type: "thread", ids: ["T01234", "C56789", "1234567890.123456"] }
|
|
7
7
|
* "jira/comment/cloud-id/PROJ-123" → { platform: "jira", type: "comment", ids: ["cloud-id", "PROJ-123"] }
|
|
8
8
|
* "builder/branch/proj-id/my-branch" → { platform: "builder", type: "branch", ids: ["proj-id", "my-branch"] }
|
|
9
|
+
* "inbox/user/builder-user-id" → { platform: "inbox", type: "user", ids: ["builder-user-id"] }
|
|
9
10
|
*/
|
|
10
11
|
export function parseChannelId(channelId) {
|
|
11
12
|
const parts = channelId.split("/");
|
|
@@ -15,3 +16,63 @@ export function parseChannelId(channelId) {
|
|
|
15
16
|
const [platform, type, ...ids] = parts;
|
|
16
17
|
return { platform, type, ids };
|
|
17
18
|
}
|
|
19
|
+
// ── Org-agent message formatting ──
|
|
20
|
+
//
|
|
21
|
+
// The org-agent receives two kinds of messages in its conversation:
|
|
22
|
+
// 1. <incoming_message> — from real users (Slack, Jira, GitHub, etc.)
|
|
23
|
+
// 2. <worker_report> — from spawned agents or branches reporting back
|
|
24
|
+
//
|
|
25
|
+
// These XML tags are consumed by the LLM (not parsed by code), so the
|
|
26
|
+
// format matters for prompt clarity and consistency.
|
|
27
|
+
const WORKER_REPORT_TRAILER = "This is a report from a background worker, NOT a user message. Review the results and take appropriate action (e.g., send findings to the user, update memory).";
|
|
28
|
+
/**
|
|
29
|
+
* Formats a `<worker_report>` message for the org-agent.
|
|
30
|
+
*
|
|
31
|
+
* Used when a spawned branch or sub-agent reports its results back.
|
|
32
|
+
* The org-agent uses `<origin_channel_id>` to route the response to the
|
|
33
|
+
* correct user channel.
|
|
34
|
+
*/
|
|
35
|
+
export function formatWorkerReport(opts) {
|
|
36
|
+
let xml = `<worker_report>\n`;
|
|
37
|
+
if (opts.originChannelId) {
|
|
38
|
+
xml += `<origin_channel_id>${opts.originChannelId}</origin_channel_id>\n`;
|
|
39
|
+
}
|
|
40
|
+
if (opts.projectId) {
|
|
41
|
+
xml += `<project_id>${opts.projectId}</project_id>\n`;
|
|
42
|
+
}
|
|
43
|
+
if (opts.branchName && opts.projectId) {
|
|
44
|
+
xml += `<branch_name>${opts.branchName}</branch_name>\n`;
|
|
45
|
+
xml += `<channel_id>builder/branch/${opts.projectId}/${opts.branchName}</channel_id>\n`;
|
|
46
|
+
}
|
|
47
|
+
if (opts.agentId) {
|
|
48
|
+
xml += `<agent_id>${opts.agentId}</agent_id>\n`;
|
|
49
|
+
}
|
|
50
|
+
xml += `<content>${opts.content}</content>\n`;
|
|
51
|
+
xml += `</worker_report>\n`;
|
|
52
|
+
xml += WORKER_REPORT_TRAILER;
|
|
53
|
+
return xml;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Formats an `<incoming_message>` for the org-agent.
|
|
57
|
+
*
|
|
58
|
+
* Used when a real user message arrives from an integration.
|
|
59
|
+
* The org-agent uses `<channel_id>` to reply in the same medium.
|
|
60
|
+
*/
|
|
61
|
+
export function formatIncomingMessage(opts) {
|
|
62
|
+
let result = "";
|
|
63
|
+
if (opts.messageContext) {
|
|
64
|
+
result += `${opts.messageContext}\n\n`;
|
|
65
|
+
}
|
|
66
|
+
result += `<incoming_message>\n`;
|
|
67
|
+
result += `<channel_id>${opts.channelId}</channel_id>\n`;
|
|
68
|
+
if (opts.dmId) {
|
|
69
|
+
result += `<dm_id>${opts.dmId}</dm_id>\n`;
|
|
70
|
+
}
|
|
71
|
+
if (opts.sender) {
|
|
72
|
+
result += `<sender>${opts.sender}</sender>\n`;
|
|
73
|
+
}
|
|
74
|
+
result += `<timestamp>${opts.timestamp}</timestamp>\n`;
|
|
75
|
+
result += `<content>${opts.content}</content>\n`;
|
|
76
|
+
result += `</incoming_message>\n`;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
package/src/codegen.d.ts
CHANGED
|
@@ -179,6 +179,8 @@ export interface AgentToolInput {
|
|
|
179
179
|
prompt: string;
|
|
180
180
|
subagent_type?: string;
|
|
181
181
|
resume?: string;
|
|
182
|
+
origin_channel_id?: string;
|
|
183
|
+
attachmentUrls?: string[];
|
|
182
184
|
}
|
|
183
185
|
export interface ListDirToolInput {
|
|
184
186
|
path: string;
|
|
@@ -499,6 +501,9 @@ export interface SpawnBranchToolInput {
|
|
|
499
501
|
hidden?: boolean;
|
|
500
502
|
sourceChannelId?: string;
|
|
501
503
|
sourceDmId?: string;
|
|
504
|
+
sessionMode?: "normal" | "planning" | "deep-research";
|
|
505
|
+
model?: "auto" | "opus" | "sonnet" | "haiku";
|
|
506
|
+
attachmentUrls?: string[];
|
|
502
507
|
}
|
|
503
508
|
export interface ReadBranchToolInput {
|
|
504
509
|
projectId: string;
|
|
@@ -1733,6 +1738,8 @@ export interface FusionConfig {
|
|
|
1733
1738
|
errorIgnorePatterns?: string[];
|
|
1734
1739
|
/** When true, sync the git working tree to the latest remote state during init */
|
|
1735
1740
|
syncBranch?: boolean;
|
|
1741
|
+
/** How the PVC was provisioned. Used by InitStateMachine to decide whether to restore from backup. */
|
|
1742
|
+
pvcCreationSource?: "fresh" | "snapshot" | "existing";
|
|
1736
1743
|
/**
|
|
1737
1744
|
* Maximum number of agent completions before pausing to ask the user to continue.
|
|
1738
1745
|
* Read from project settings, with fallback to organization/space settings.
|
|
@@ -1772,7 +1779,7 @@ export interface LoadHistoryResult {
|
|
|
1772
1779
|
updatedUnixTime: number;
|
|
1773
1780
|
turns: CodegenTurn[];
|
|
1774
1781
|
}
|
|
1775
|
-
export type InitStateStep = "initial" | "init" | "validation" | "check-directories" | "create-directories" | "configure-git-repos" | "check-existing-git" | "update-remote-url" | "clone-repo" | "apply-partial-backup" | "configure-git-user" | "stash-changes" | "collect-repo-info" | "init-success" | "init-command" | "init-failed" | "snapshot-git-sync";
|
|
1782
|
+
export type InitStateStep = "initial" | "init" | "validation" | "check-directories" | "create-directories" | "configure-git-repos" | "check-existing-git" | "update-remote-url" | "clone-repo" | "apply-partial-backup" | "configure-git-user" | "stash-changes" | "collect-repo-info" | "init-success" | "init-command" | "init-failed" | "snapshot-git-sync" | "snapshot-backup-restore";
|
|
1776
1783
|
export interface InitStatusLog {
|
|
1777
1784
|
id: number;
|
|
1778
1785
|
timestamp: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import net from "net";
|
|
1
2
|
import type { CheckResult, Source, TestId } from "../types.js";
|
|
2
3
|
export interface TcpCheckOptions {
|
|
3
4
|
hostname: string;
|
|
@@ -5,5 +6,7 @@ export interface TcpCheckOptions {
|
|
|
5
6
|
source: Source;
|
|
6
7
|
testId: TestId;
|
|
7
8
|
timeout?: number;
|
|
9
|
+
/** Provide a pre-connected socket (e.g. tunneled through a proxy via CONNECT). */
|
|
10
|
+
connectFn?: (hostname: string, port: number) => Promise<net.Socket>;
|
|
8
11
|
}
|
|
9
12
|
export declare function tcpCheck(options: TcpCheckOptions): Promise<CheckResult>;
|
|
@@ -4,11 +4,29 @@ const DEFAULT_TIMEOUT_MS = 5000;
|
|
|
4
4
|
const DEFAULT_PORT = 443;
|
|
5
5
|
export async function tcpCheck(options) {
|
|
6
6
|
var _a, _b;
|
|
7
|
-
const { hostname, port = DEFAULT_PORT, source, testId, timeout = DEFAULT_TIMEOUT_MS, } = options;
|
|
7
|
+
const { hostname, port = DEFAULT_PORT, source, testId, timeout = DEFAULT_TIMEOUT_MS, connectFn, } = options;
|
|
8
8
|
const target = `${hostname}:${port}`;
|
|
9
9
|
const startTime = Date.now();
|
|
10
10
|
try {
|
|
11
11
|
const result = await new Promise((resolve) => {
|
|
12
|
+
if (connectFn) {
|
|
13
|
+
const timer = setTimeout(() => {
|
|
14
|
+
const error = new Error("Connection timed out");
|
|
15
|
+
error.code = "ETIMEDOUT";
|
|
16
|
+
resolve({ success: false, error });
|
|
17
|
+
}, timeout);
|
|
18
|
+
connectFn(hostname, port)
|
|
19
|
+
.then((socket) => {
|
|
20
|
+
clearTimeout(timer);
|
|
21
|
+
socket.destroy();
|
|
22
|
+
resolve({ success: true });
|
|
23
|
+
})
|
|
24
|
+
.catch((err) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
resolve({ success: false, error: err });
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
12
30
|
const socket = new net.Socket();
|
|
13
31
|
socket.setTimeout(timeout);
|
|
14
32
|
socket.on("connect", () => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type net from "net";
|
|
1
2
|
import type { CheckResult, Source, TestId } from "../types.js";
|
|
2
3
|
export interface TlsCheckOptions {
|
|
3
4
|
hostname: string;
|
|
@@ -5,5 +6,7 @@ export interface TlsCheckOptions {
|
|
|
5
6
|
source: Source;
|
|
6
7
|
testId: TestId;
|
|
7
8
|
timeout?: number;
|
|
9
|
+
/** Provide a pre-connected socket (e.g. tunneled through a proxy via CONNECT). TLS upgrade happens on top. */
|
|
10
|
+
connectFn?: (hostname: string, port: number) => Promise<net.Socket>;
|
|
8
11
|
}
|
|
9
12
|
export declare function tlsCheck(options: TlsCheckOptions): Promise<CheckResult>;
|
|
@@ -4,10 +4,38 @@ const DEFAULT_TIMEOUT_MS = 10000;
|
|
|
4
4
|
const DEFAULT_PORT = 443;
|
|
5
5
|
export async function tlsCheck(options) {
|
|
6
6
|
var _a, _b;
|
|
7
|
-
const { hostname, port = DEFAULT_PORT, source, testId, timeout = DEFAULT_TIMEOUT_MS, } = options;
|
|
7
|
+
const { hostname, port = DEFAULT_PORT, source, testId, timeout = DEFAULT_TIMEOUT_MS, connectFn, } = options;
|
|
8
8
|
const target = `${hostname}:${port}`;
|
|
9
9
|
const startTime = Date.now();
|
|
10
10
|
try {
|
|
11
|
+
let tunnelSocket;
|
|
12
|
+
if (connectFn) {
|
|
13
|
+
let timedOut = false;
|
|
14
|
+
const connectPromise = connectFn(hostname, port);
|
|
15
|
+
tunnelSocket = await new Promise((resolve, reject) => {
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
timedOut = true;
|
|
18
|
+
connectPromise.then((s) => s.destroy()).catch(() => { });
|
|
19
|
+
const error = new Error("Proxy CONNECT timed out");
|
|
20
|
+
error.code = "ETIMEDOUT";
|
|
21
|
+
reject(error);
|
|
22
|
+
}, timeout);
|
|
23
|
+
connectPromise
|
|
24
|
+
.then((socket) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
if (timedOut) {
|
|
27
|
+
socket.destroy();
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
resolve(socket);
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
.catch((err) => {
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
reject(err);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
11
39
|
const result = await new Promise((resolve) => {
|
|
12
40
|
const socket = tls.connect({
|
|
13
41
|
host: hostname,
|
|
@@ -15,6 +43,7 @@ export async function tlsCheck(options) {
|
|
|
15
43
|
servername: hostname, // SNI required for virtual hosts
|
|
16
44
|
rejectUnauthorized: true,
|
|
17
45
|
timeout,
|
|
46
|
+
...(tunnelSocket ? { socket: tunnelSocket } : {}),
|
|
18
47
|
}, () => {
|
|
19
48
|
const cert = socket.getPeerCertificate();
|
|
20
49
|
let certInfo;
|
|
@@ -6,7 +6,7 @@ import { tcpCheck } from "./checks/tcp-check.js";
|
|
|
6
6
|
import { tlsCheck } from "./checks/tls-check.js";
|
|
7
7
|
import { sshCheck } from "./checks/ssh-check.js";
|
|
8
8
|
export async function runChecks(input) {
|
|
9
|
-
const { tests, gitHost, onProgress, fetchFn, dispatcher } = input;
|
|
9
|
+
const { tests, gitHost, onProgress, fetchFn, dispatcher, connectFn } = input;
|
|
10
10
|
const results = [];
|
|
11
11
|
const total = tests.length;
|
|
12
12
|
for (let index = 0; index < tests.length; index++) {
|
|
@@ -17,7 +17,7 @@ export async function runChecks(input) {
|
|
|
17
17
|
index,
|
|
18
18
|
total,
|
|
19
19
|
});
|
|
20
|
-
const result = await runSingleCheck(test, gitHost, fetchFn, dispatcher);
|
|
20
|
+
const result = await runSingleCheck(test, gitHost, fetchFn, dispatcher, connectFn);
|
|
21
21
|
results.push(result);
|
|
22
22
|
emitProgress(onProgress, {
|
|
23
23
|
type: "test:complete",
|
|
@@ -36,7 +36,7 @@ export async function runChecks(input) {
|
|
|
36
36
|
results,
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
async function runSingleCheck(test, gitHost, fetchFn, dispatcher) {
|
|
39
|
+
async function runSingleCheck(test, gitHost, fetchFn, dispatcher, connectFn) {
|
|
40
40
|
const { source, testId } = test;
|
|
41
41
|
const checkType = getCheckTypeForTestId(testId);
|
|
42
42
|
if (!isCheckAvailable(checkType)) {
|
|
@@ -93,6 +93,7 @@ async function runSingleCheck(test, gitHost, fetchFn, dispatcher) {
|
|
|
93
93
|
port: extractPort(target, 443),
|
|
94
94
|
source,
|
|
95
95
|
testId,
|
|
96
|
+
connectFn: connectFn,
|
|
96
97
|
});
|
|
97
98
|
case "tls":
|
|
98
99
|
return tlsCheck({
|
|
@@ -100,6 +101,7 @@ async function runSingleCheck(test, gitHost, fetchFn, dispatcher) {
|
|
|
100
101
|
port: extractPort(target, 443),
|
|
101
102
|
source,
|
|
102
103
|
testId,
|
|
104
|
+
connectFn: connectFn,
|
|
103
105
|
});
|
|
104
106
|
case "ssh":
|
|
105
107
|
return sshCheck({
|
|
@@ -25,6 +25,12 @@ export interface RunChecksInput {
|
|
|
25
25
|
* Typically only needed server-side for static IP routing.
|
|
26
26
|
*/
|
|
27
27
|
dispatcher?: object;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a connected socket tunneled through a proxy (via HTTP CONNECT).
|
|
30
|
+
* Used by TCP and TLS checks for static IP routing. The returned socket
|
|
31
|
+
* is already connected to hostname:port through the proxy.
|
|
32
|
+
*/
|
|
33
|
+
connectFn?: (hostname: string, port: number) => Promise<unknown>;
|
|
28
34
|
}
|
|
29
35
|
export type ProgressEvent = {
|
|
30
36
|
type: "test:start";
|
package/src/projects.d.ts
CHANGED
|
@@ -775,6 +775,7 @@ export interface CreateBranchOptions {
|
|
|
775
775
|
featureFlags?: Record<string, boolean>;
|
|
776
776
|
checkoutBranch?: string | null;
|
|
777
777
|
canHandleTools?: (keyof CodeGenToolMap)[];
|
|
778
|
+
skipPromptAnalysis?: boolean;
|
|
778
779
|
useKube?: boolean;
|
|
779
780
|
fireAndForget?: boolean;
|
|
780
781
|
/** PR number for QA bot branches */
|
|
@@ -789,13 +790,6 @@ export interface CreateBranchOptions {
|
|
|
789
790
|
}
|
|
790
791
|
interface BaseCreateBranchMessage {
|
|
791
792
|
}
|
|
792
|
-
export interface ValidatingProjectMessage extends BaseCreateBranchMessage {
|
|
793
|
-
type: "validating-project";
|
|
794
|
-
message: string;
|
|
795
|
-
projectId: string;
|
|
796
|
-
projectName?: string;
|
|
797
|
-
branchName: string;
|
|
798
|
-
}
|
|
799
793
|
export interface CreatingBranchMessage extends BaseCreateBranchMessage {
|
|
800
794
|
type: "creating-branch";
|
|
801
795
|
message: string;
|
|
@@ -811,6 +805,7 @@ export interface SettingUpContainerMessage extends BaseCreateBranchMessage {
|
|
|
811
805
|
projectName: string;
|
|
812
806
|
branchName: string;
|
|
813
807
|
branchFriendlyName: string | undefined;
|
|
808
|
+
branchDescription: string | undefined;
|
|
814
809
|
}
|
|
815
810
|
export interface ContainerReadyMessage extends BaseCreateBranchMessage {
|
|
816
811
|
type: "container-ready";
|
|
@@ -851,7 +846,7 @@ export interface AiMessage extends BaseCreateBranchMessage {
|
|
|
851
846
|
type: "ai";
|
|
852
847
|
event: GenerateCompletionStep;
|
|
853
848
|
}
|
|
854
|
-
export type CreateBranchChunkMessage =
|
|
849
|
+
export type CreateBranchChunkMessage = CreatingBranchMessage | SettingUpContainerMessage | SendingInitialMessageMessage | BranchCreatedMessage | CreateBranchErrorMessage | EnsureContainerMessage | ContainerReadyMessage | AiMessage;
|
|
855
850
|
export interface CreateBranchResponse {
|
|
856
851
|
success: boolean;
|
|
857
852
|
branchName?: string;
|
|
@@ -938,12 +933,6 @@ export interface ValidatingBranchMessage extends BaseSendMessageMessage {
|
|
|
938
933
|
projectId: string;
|
|
939
934
|
branchName: string;
|
|
940
935
|
}
|
|
941
|
-
export interface SettingUpContainerMessage extends BaseSendMessageMessage {
|
|
942
|
-
type: "setting-up-container";
|
|
943
|
-
message: string;
|
|
944
|
-
projectId: string;
|
|
945
|
-
branchName: string;
|
|
946
|
-
}
|
|
947
936
|
export interface SendingMessageMessage extends BaseSendMessageMessage {
|
|
948
937
|
type: "sending-message";
|
|
949
938
|
message: string;
|