@prbe.ai/electron-sdk 0.1.13 → 0.1.14
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/dist/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +237 -227
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +236 -227
- package/dist/index.mjs.map +1 -1
- package/dist/{types-B_KS1-FJ.d.mts → types-Bn2vj7rp.d.mts} +27 -11
- package/dist/{types-B_KS1-FJ.d.ts → types-Bn2vj7rp.d.ts} +27 -11
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/dist/types.mjs +3 -0
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9,6 +9,7 @@ var WSMessageType = /* @__PURE__ */ ((WSMessageType2) => {
|
|
|
9
9
|
WSMessageType2["START"] = "start";
|
|
10
10
|
WSMessageType2["TOOL_RESULT"] = "tool_result";
|
|
11
11
|
WSMessageType2["UPLOAD_REQUEST"] = "upload_request";
|
|
12
|
+
WSMessageType2["CONVERSATION_MESSAGE"] = "conversation_message";
|
|
12
13
|
WSMessageType2["CANCEL"] = "cancel";
|
|
13
14
|
WSMessageType2["PONG"] = "pong";
|
|
14
15
|
WSMessageType2["THOUGHT"] = "thought";
|
|
@@ -17,11 +18,17 @@ var WSMessageType = /* @__PURE__ */ ((WSMessageType2) => {
|
|
|
17
18
|
WSMessageType2["SERVER_OBSERVATION"] = "server_observation";
|
|
18
19
|
WSMessageType2["UPLOAD_URL"] = "upload_url";
|
|
19
20
|
WSMessageType2["SESSION_CONFIG"] = "session_config";
|
|
21
|
+
WSMessageType2["CONVERSATION_UPDATE"] = "conversation_update";
|
|
20
22
|
WSMessageType2["COMPLETE"] = "complete";
|
|
21
23
|
WSMessageType2["ERROR"] = "error";
|
|
22
24
|
WSMessageType2["PING"] = "ping";
|
|
23
25
|
return WSMessageType2;
|
|
24
26
|
})(WSMessageType || {});
|
|
27
|
+
var ConversationRole = /* @__PURE__ */ ((ConversationRole3) => {
|
|
28
|
+
ConversationRole3["User"] = "user";
|
|
29
|
+
ConversationRole3["Agent"] = "agent";
|
|
30
|
+
return ConversationRole3;
|
|
31
|
+
})(ConversationRole || {});
|
|
25
32
|
var ToolParamType = /* @__PURE__ */ ((ToolParamType2) => {
|
|
26
33
|
ToolParamType2["STRING"] = "STRING";
|
|
27
34
|
ToolParamType2["BOOLEAN"] = "BOOLEAN";
|
|
@@ -91,6 +98,83 @@ function redactPII(text) {
|
|
|
91
98
|
var API_URL = "https://api.prbe.ai";
|
|
92
99
|
var MIDDLEWARE_URL = "wss://middleware.prbe.ai";
|
|
93
100
|
|
|
101
|
+
// src/connection.ts
|
|
102
|
+
var InvestigationConnection = class {
|
|
103
|
+
constructor(url, apiKey, onMessage, onError, onClose) {
|
|
104
|
+
this.onMessage = onMessage;
|
|
105
|
+
this.onError = onError;
|
|
106
|
+
this.onClose = onClose;
|
|
107
|
+
this.ws = new WebSocket(url, {
|
|
108
|
+
headers: { "X-API-Key": apiKey }
|
|
109
|
+
});
|
|
110
|
+
this.ws.onmessage = (event) => {
|
|
111
|
+
const raw = typeof event.data === "string" ? event.data : event.data instanceof Buffer ? event.data.toString("utf-8") : null;
|
|
112
|
+
if (!raw) return;
|
|
113
|
+
try {
|
|
114
|
+
const msg = JSON.parse(raw);
|
|
115
|
+
this.onMessage(msg);
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
this.ws.onerror = (event) => {
|
|
120
|
+
const errorEvent = event;
|
|
121
|
+
this.onError(errorEvent.message || "WebSocket connection error");
|
|
122
|
+
};
|
|
123
|
+
this.ws.onclose = () => {
|
|
124
|
+
this.onClose();
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
ws;
|
|
128
|
+
closed = false;
|
|
129
|
+
get isOpen() {
|
|
130
|
+
return !this.closed && this.ws.readyState === WebSocket.OPEN;
|
|
131
|
+
}
|
|
132
|
+
send(msg) {
|
|
133
|
+
if (!this.isOpen) return false;
|
|
134
|
+
try {
|
|
135
|
+
this.ws.send(JSON.stringify(msg));
|
|
136
|
+
return true;
|
|
137
|
+
} catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
sendConversationMessage(content) {
|
|
142
|
+
this.send({
|
|
143
|
+
type: "conversation_message" /* CONVERSATION_MESSAGE */,
|
|
144
|
+
content
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
sendToolResult(callId, toolName, result, metadata) {
|
|
148
|
+
this.send({
|
|
149
|
+
type: "tool_result" /* TOOL_RESULT */,
|
|
150
|
+
id: callId,
|
|
151
|
+
name: toolName,
|
|
152
|
+
content: result,
|
|
153
|
+
metadata
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
sendCancel() {
|
|
157
|
+
this.send({ type: "cancel" /* CANCEL */ });
|
|
158
|
+
}
|
|
159
|
+
sendPong() {
|
|
160
|
+
this.send({ type: "pong" /* PONG */ });
|
|
161
|
+
}
|
|
162
|
+
close(code = 1e3, reason) {
|
|
163
|
+
if (this.closed) return;
|
|
164
|
+
this.closed = true;
|
|
165
|
+
try {
|
|
166
|
+
this.ws.close(code, reason);
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Set the onopen handler. Called when the connection is ready to send messages.
|
|
172
|
+
*/
|
|
173
|
+
set onopen(handler) {
|
|
174
|
+
this.ws.onopen = handler;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
94
178
|
// src/state.ts
|
|
95
179
|
import { EventEmitter } from "events";
|
|
96
180
|
import { randomUUID } from "crypto";
|
|
@@ -119,6 +203,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
119
203
|
pendingInteraction;
|
|
120
204
|
resolvedInteractions = [];
|
|
121
205
|
agentMessage;
|
|
206
|
+
conversationHistory = [];
|
|
122
207
|
// Completed user investigations (history)
|
|
123
208
|
completedInvestigations = [];
|
|
124
209
|
// Background context requests
|
|
@@ -142,6 +227,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
142
227
|
this.isInvestigating = true;
|
|
143
228
|
this.events = [];
|
|
144
229
|
this.resolvedInteractions = [];
|
|
230
|
+
this.conversationHistory = [];
|
|
145
231
|
this.report = "";
|
|
146
232
|
this.summary = "";
|
|
147
233
|
this.currentQuery = query;
|
|
@@ -149,10 +235,15 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
149
235
|
this.agentMessage = void 0;
|
|
150
236
|
this.emit("status" /* STATUS */);
|
|
151
237
|
}
|
|
238
|
+
appendConversation(entry) {
|
|
239
|
+
this.conversationHistory.push(entry);
|
|
240
|
+
this.emit("status" /* STATUS */);
|
|
241
|
+
}
|
|
152
242
|
resetInvestigation() {
|
|
153
243
|
this.isInvestigating = false;
|
|
154
244
|
this.events = [];
|
|
155
245
|
this.resolvedInteractions = [];
|
|
246
|
+
this.conversationHistory = [];
|
|
156
247
|
this.report = "";
|
|
157
248
|
this.summary = "";
|
|
158
249
|
this.currentQuery = "";
|
|
@@ -185,7 +276,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
185
276
|
this.emit("status" /* STATUS */);
|
|
186
277
|
}
|
|
187
278
|
}
|
|
188
|
-
completeInvestigation(report,
|
|
279
|
+
completeInvestigation(report, ticketId) {
|
|
189
280
|
if (this.events.length > 0) {
|
|
190
281
|
this.events[this.events.length - 1].isCompleted = true;
|
|
191
282
|
}
|
|
@@ -194,16 +285,15 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
194
285
|
id: randomUUID(),
|
|
195
286
|
query: this.currentQuery,
|
|
196
287
|
report,
|
|
197
|
-
summary,
|
|
198
288
|
ticketId,
|
|
199
289
|
events: [...this.events],
|
|
200
290
|
resolvedInteractions: [...this.resolvedInteractions],
|
|
291
|
+
conversationHistory: [...this.conversationHistory],
|
|
201
292
|
completedAt: /* @__PURE__ */ new Date()
|
|
202
293
|
});
|
|
203
294
|
this.report = report;
|
|
204
|
-
this.summary = summary;
|
|
205
295
|
this.isInvestigating = false;
|
|
206
|
-
this.emit("complete" /* COMPLETE */, { report
|
|
296
|
+
this.emit("complete" /* COMPLETE */, { report });
|
|
207
297
|
this.emit("status" /* STATUS */);
|
|
208
298
|
}
|
|
209
299
|
failInvestigation(message) {
|
|
@@ -328,7 +418,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
328
418
|
cr.events[cr.events.length - 1].detail = text;
|
|
329
419
|
this.emit("status" /* STATUS */);
|
|
330
420
|
}
|
|
331
|
-
completeCR(id, report
|
|
421
|
+
completeCR(id, report) {
|
|
332
422
|
const cr = this.activeCRs.get(id);
|
|
333
423
|
if (!cr) return;
|
|
334
424
|
this.activeCRs.delete(id);
|
|
@@ -344,7 +434,6 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
344
434
|
cr.isRunning = false;
|
|
345
435
|
cr.isCompleted = true;
|
|
346
436
|
cr.report = report;
|
|
347
|
-
cr.summary = summary;
|
|
348
437
|
this.completedCRs.unshift(cr);
|
|
349
438
|
this.emit("cr-complete" /* CR_COMPLETE */, cr);
|
|
350
439
|
this.emit("status" /* STATUS */);
|
|
@@ -1281,9 +1370,9 @@ var AskUserTool = class {
|
|
|
1281
1370
|
required: true
|
|
1282
1371
|
},
|
|
1283
1372
|
{
|
|
1284
|
-
name: "
|
|
1373
|
+
name: "reason",
|
|
1285
1374
|
type: "STRING" /* STRING */,
|
|
1286
|
-
description: "
|
|
1375
|
+
description: "Short reason displayed alongside the input prompt explaining why you need this information",
|
|
1287
1376
|
required: false
|
|
1288
1377
|
}
|
|
1289
1378
|
]
|
|
@@ -1295,12 +1384,11 @@ var AskUserTool = class {
|
|
|
1295
1384
|
if (this.requester.investigationSource !== "user" /* USER */) {
|
|
1296
1385
|
return "This is a context request investigation \u2014 you cannot ask the user questions. Use the available tools to answer the query autonomously.";
|
|
1297
1386
|
}
|
|
1298
|
-
const
|
|
1387
|
+
const reason = args["reason"] ?? "Waiting for your response";
|
|
1299
1388
|
const response = await this.requester.requestUserInteraction({
|
|
1300
1389
|
type: "ask_question" /* ASK_QUESTION */,
|
|
1301
1390
|
interactionId: randomUUID3(),
|
|
1302
|
-
question
|
|
1303
|
-
context
|
|
1391
|
+
question: reason
|
|
1304
1392
|
});
|
|
1305
1393
|
const askResponse = response;
|
|
1306
1394
|
return askResponse.answer;
|
|
@@ -1721,6 +1809,7 @@ var HistoryStore = class {
|
|
|
1721
1809
|
ticketId: inv.ticketId,
|
|
1722
1810
|
events: inv.events,
|
|
1723
1811
|
resolvedInteractions: inv.resolvedInteractions,
|
|
1812
|
+
conversationHistory: inv.conversationHistory,
|
|
1724
1813
|
completedAt: inv.completedAt.toISOString()
|
|
1725
1814
|
};
|
|
1726
1815
|
fs2.writeFileSync(
|
|
@@ -1813,7 +1902,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1813
1902
|
registry = new PRBEToolRegistry();
|
|
1814
1903
|
grantedPaths = /* @__PURE__ */ new Set();
|
|
1815
1904
|
userCancelled = false;
|
|
1816
|
-
|
|
1905
|
+
activeConnection = null;
|
|
1817
1906
|
pollingTimer = null;
|
|
1818
1907
|
persistedData;
|
|
1819
1908
|
fetchAbortController = null;
|
|
@@ -1973,6 +2062,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1973
2062
|
get investigationSource() {
|
|
1974
2063
|
return this.currentInvestigationSource;
|
|
1975
2064
|
}
|
|
2065
|
+
sendConversationMessage(content) {
|
|
2066
|
+
this.activeConnection?.sendConversationMessage(content);
|
|
2067
|
+
}
|
|
1976
2068
|
async requestUserInteraction(payload) {
|
|
1977
2069
|
if (!this.interactionHandler) {
|
|
1978
2070
|
throw new PRBEAgentError(
|
|
@@ -1992,6 +2084,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1992
2084
|
} else {
|
|
1993
2085
|
this.state.resolveInteraction(response);
|
|
1994
2086
|
}
|
|
2087
|
+
if (response.type === "request_permission" /* REQUEST_PERMISSION */) {
|
|
2088
|
+
const approved = response.approved;
|
|
2089
|
+
this.sendConversationMessage(approved ? "Approved" : "Denied");
|
|
2090
|
+
} else if (response.type === "request_path_access" /* REQUEST_PATH_ACCESS */) {
|
|
2091
|
+
const granted = response.granted;
|
|
2092
|
+
this.sendConversationMessage(granted ? "Allowed" : "Denied");
|
|
2093
|
+
}
|
|
1995
2094
|
return response;
|
|
1996
2095
|
} catch (err) {
|
|
1997
2096
|
if (this.currentInvestigationSource === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
|
|
@@ -2044,7 +2143,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2044
2143
|
this.state.appendEvent("Thinking", status.text);
|
|
2045
2144
|
break;
|
|
2046
2145
|
case "completed" /* COMPLETED */:
|
|
2047
|
-
this.state.completeInvestigation(status.report, status.
|
|
2146
|
+
this.state.completeInvestigation(status.report, status.ticketId);
|
|
2048
2147
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2049
2148
|
break;
|
|
2050
2149
|
case "error" /* ERROR */:
|
|
@@ -2074,9 +2173,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2074
2173
|
*/
|
|
2075
2174
|
cancelInvestigation() {
|
|
2076
2175
|
this.userCancelled = true;
|
|
2077
|
-
if (this.
|
|
2078
|
-
this.
|
|
2079
|
-
this.
|
|
2176
|
+
if (this.activeConnection) {
|
|
2177
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2178
|
+
this.activeConnection = null;
|
|
2080
2179
|
}
|
|
2081
2180
|
}
|
|
2082
2181
|
/**
|
|
@@ -2084,9 +2183,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2084
2183
|
*/
|
|
2085
2184
|
cancel() {
|
|
2086
2185
|
this.userCancelled = true;
|
|
2087
|
-
if (this.
|
|
2088
|
-
this.
|
|
2089
|
-
this.
|
|
2186
|
+
if (this.activeConnection) {
|
|
2187
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2188
|
+
this.activeConnection = null;
|
|
2090
2189
|
}
|
|
2091
2190
|
this.abortInFlightRequests();
|
|
2092
2191
|
this.stopPolling();
|
|
@@ -2225,7 +2324,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2225
2324
|
this.state.appendCREvent(crID, "Thinking", status.text);
|
|
2226
2325
|
break;
|
|
2227
2326
|
case "completed" /* COMPLETED */:
|
|
2228
|
-
this.state.completeCR(crID, status.report
|
|
2327
|
+
this.state.completeCR(crID, status.report);
|
|
2229
2328
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2230
2329
|
break;
|
|
2231
2330
|
case "error" /* ERROR */:
|
|
@@ -2252,31 +2351,44 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2252
2351
|
connectToProxy(query, contextRequestID, emit, isCancelled, ticketId) {
|
|
2253
2352
|
return new Promise((resolve2) => {
|
|
2254
2353
|
const wsUrl = `${MIDDLEWARE_URL}/api/agent/client/ws`;
|
|
2255
|
-
let ws;
|
|
2256
|
-
try {
|
|
2257
|
-
ws = new WebSocket(wsUrl, {
|
|
2258
|
-
headers: {
|
|
2259
|
-
"X-API-Key": this.config.apiKey
|
|
2260
|
-
}
|
|
2261
|
-
});
|
|
2262
|
-
} catch (err) {
|
|
2263
|
-
emit({
|
|
2264
|
-
type: "error" /* ERROR */,
|
|
2265
|
-
message: `Failed to create WebSocket: ${err}`
|
|
2266
|
-
});
|
|
2267
|
-
resolve2(null);
|
|
2268
|
-
return;
|
|
2269
|
-
}
|
|
2270
|
-
this.activeWS = ws;
|
|
2271
2354
|
let uploadBaseUrl;
|
|
2272
2355
|
let resolved = false;
|
|
2273
2356
|
const finish = (result) => {
|
|
2274
2357
|
if (resolved) return;
|
|
2275
2358
|
resolved = true;
|
|
2276
|
-
this.
|
|
2359
|
+
this.activeConnection = null;
|
|
2277
2360
|
resolve2(result);
|
|
2278
2361
|
};
|
|
2279
|
-
|
|
2362
|
+
let conn;
|
|
2363
|
+
try {
|
|
2364
|
+
conn = new InvestigationConnection(
|
|
2365
|
+
wsUrl,
|
|
2366
|
+
this.config.apiKey,
|
|
2367
|
+
(msg) => this.handleMessage(msg, conn, emit, isCancelled, finish, () => uploadBaseUrl, (url) => {
|
|
2368
|
+
uploadBaseUrl = url;
|
|
2369
|
+
}),
|
|
2370
|
+
(message) => {
|
|
2371
|
+
if (!isCancelled()) emit({ type: "error" /* ERROR */, message });
|
|
2372
|
+
finish(null);
|
|
2373
|
+
},
|
|
2374
|
+
() => {
|
|
2375
|
+
if (!resolved) {
|
|
2376
|
+
if (isCancelled()) {
|
|
2377
|
+
finish(null);
|
|
2378
|
+
} else {
|
|
2379
|
+
emit({ type: "error" /* ERROR */, message: "WebSocket connection closed unexpectedly" });
|
|
2380
|
+
finish(null);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
);
|
|
2385
|
+
} catch (err) {
|
|
2386
|
+
emit({ type: "error" /* ERROR */, message: `Failed to create WebSocket: ${err}` });
|
|
2387
|
+
resolve2(null);
|
|
2388
|
+
return;
|
|
2389
|
+
}
|
|
2390
|
+
this.activeConnection = conn;
|
|
2391
|
+
conn.onopen = () => {
|
|
2280
2392
|
const toolDeclarations = this.registry.allDeclarations().map((decl) => ({
|
|
2281
2393
|
name: decl.name,
|
|
2282
2394
|
description: decl.description,
|
|
@@ -2295,206 +2407,99 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2295
2407
|
os_version: os2.release(),
|
|
2296
2408
|
arch: os2.arch()
|
|
2297
2409
|
};
|
|
2298
|
-
if (contextRequestID)
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
if (
|
|
2302
|
-
|
|
2303
|
-
}
|
|
2304
|
-
if (this.appDataPath) {
|
|
2305
|
-
startMetadata["app_data_path"] = this.appDataPath;
|
|
2306
|
-
}
|
|
2307
|
-
const startMsg = {
|
|
2308
|
-
type: "start" /* START */,
|
|
2309
|
-
content: query,
|
|
2310
|
-
metadata: startMetadata
|
|
2311
|
-
};
|
|
2312
|
-
try {
|
|
2313
|
-
ws.send(JSON.stringify(startMsg));
|
|
2314
|
-
} catch (err) {
|
|
2315
|
-
emit({
|
|
2316
|
-
type: "error" /* ERROR */,
|
|
2317
|
-
message: `Failed to send start message: ${err}`
|
|
2318
|
-
});
|
|
2410
|
+
if (contextRequestID) startMetadata["context_request_id"] = contextRequestID;
|
|
2411
|
+
if (ticketId) startMetadata["ticket_id"] = ticketId;
|
|
2412
|
+
if (this.appDataPath) startMetadata["app_data_path"] = this.appDataPath;
|
|
2413
|
+
if (!conn.send({ type: "start" /* START */, content: query, metadata: startMetadata })) {
|
|
2414
|
+
emit({ type: "error" /* ERROR */, message: "Failed to send start message" });
|
|
2319
2415
|
finish(null);
|
|
2320
2416
|
return;
|
|
2321
2417
|
}
|
|
2322
2418
|
emit({ type: "started" /* STARTED */ });
|
|
2323
2419
|
this.pendingFlaggedFiles = [];
|
|
2324
2420
|
};
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
}
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
const
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
label: msg.content ?? `Running ${toolName}`
|
|
2361
|
-
});
|
|
2362
|
-
this.pendingFlaggedFiles = [];
|
|
2363
|
-
const toolResult = redactPII(
|
|
2364
|
-
await this.registry.execute(toolName, args)
|
|
2365
|
-
);
|
|
2366
|
-
emit({
|
|
2367
|
-
type: "observation" /* OBSERVATION */,
|
|
2368
|
-
text: toolResult.substring(0, 200)
|
|
2369
|
-
});
|
|
2370
|
-
let resultMetadata;
|
|
2371
|
-
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2372
|
-
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2373
|
-
const uploadedRefs = [];
|
|
2374
|
-
for (const file of this.pendingFlaggedFiles) {
|
|
2375
|
-
const filename = path5.basename(file.originalPath);
|
|
2376
|
-
const safeName = encodeURIComponent(filename);
|
|
2377
|
-
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2378
|
-
uploadedRefs.push({
|
|
2379
|
-
original_path: file.originalPath,
|
|
2380
|
-
reason: file.reason ?? "",
|
|
2381
|
-
storage_path: storagePath,
|
|
2382
|
-
file_size_bytes: file.data.length
|
|
2383
|
-
});
|
|
2384
|
-
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2385
|
-
const fileData = file.data;
|
|
2386
|
-
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2387
|
-
void _PRBEAgent.backgroundUpload(
|
|
2388
|
-
fileData,
|
|
2389
|
-
uploadUrl,
|
|
2390
|
-
this.config.apiKey,
|
|
2391
|
-
contentType,
|
|
2392
|
-
this.getFetchSignal()
|
|
2393
|
-
);
|
|
2394
|
-
}
|
|
2395
|
-
resultMetadata = { flagged_files: uploadedRefs };
|
|
2396
|
-
this.pendingFlaggedFiles = [];
|
|
2397
|
-
}
|
|
2398
|
-
const resultMsg = {
|
|
2399
|
-
type: "tool_result" /* TOOL_RESULT */,
|
|
2400
|
-
id: callId,
|
|
2401
|
-
name: toolName,
|
|
2402
|
-
content: toolResult,
|
|
2403
|
-
metadata: resultMetadata
|
|
2404
|
-
};
|
|
2405
|
-
try {
|
|
2406
|
-
ws.send(JSON.stringify(resultMsg));
|
|
2407
|
-
} catch {
|
|
2408
|
-
}
|
|
2409
|
-
break;
|
|
2410
|
-
}
|
|
2411
|
-
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2412
|
-
emit({
|
|
2413
|
-
type: "tool_call" /* TOOL_CALL */,
|
|
2414
|
-
name: msg.name ?? "",
|
|
2415
|
-
label: msg.content ?? ""
|
|
2416
|
-
});
|
|
2417
|
-
break;
|
|
2418
|
-
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2419
|
-
emit({
|
|
2420
|
-
type: "observation" /* OBSERVATION */,
|
|
2421
|
-
text: (msg.content ?? "").substring(0, 200)
|
|
2422
|
-
});
|
|
2423
|
-
break;
|
|
2424
|
-
case "complete" /* COMPLETE */: {
|
|
2425
|
-
const report = msg.content ?? "";
|
|
2426
|
-
const userSummary = msg.metadata?.["user_summary"] ?? "";
|
|
2427
|
-
const ticketId2 = msg.metadata?.["ticket_id"];
|
|
2428
|
-
const sessionId = msg.metadata?.["session_id"];
|
|
2429
|
-
emit({
|
|
2430
|
-
type: "completed" /* COMPLETED */,
|
|
2431
|
-
report,
|
|
2432
|
-
userSummary,
|
|
2433
|
-
ticketId: ticketId2
|
|
2434
|
-
});
|
|
2435
|
-
ws.close(1e3, "Complete");
|
|
2436
|
-
finish({ report, userSummary, ticketId: ticketId2, sessionId });
|
|
2437
|
-
break;
|
|
2438
|
-
}
|
|
2439
|
-
case "error" /* ERROR */:
|
|
2440
|
-
emit({
|
|
2441
|
-
type: "error" /* ERROR */,
|
|
2442
|
-
message: msg.content || "Unknown error"
|
|
2421
|
+
});
|
|
2422
|
+
}
|
|
2423
|
+
async handleMessage(msg, conn, emit, isCancelled, finish, getUploadBaseUrl, setUploadBaseUrl) {
|
|
2424
|
+
if (isCancelled()) {
|
|
2425
|
+
conn.sendCancel();
|
|
2426
|
+
conn.close(1e3, "Cancelled");
|
|
2427
|
+
finish(null);
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
switch (msg.type) {
|
|
2431
|
+
case "thought" /* THOUGHT */:
|
|
2432
|
+
emit({ type: "thought" /* THOUGHT */, text: msg.content ?? "" });
|
|
2433
|
+
break;
|
|
2434
|
+
case "tool_call" /* TOOL_CALL */: {
|
|
2435
|
+
const toolName = msg.name ?? "";
|
|
2436
|
+
const callId = msg.id ?? "";
|
|
2437
|
+
const args = this.extractArgs(msg.metadata);
|
|
2438
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: toolName, label: msg.content ?? `Running ${toolName}` });
|
|
2439
|
+
this.pendingFlaggedFiles = [];
|
|
2440
|
+
const toolResult = redactPII(await this.registry.execute(toolName, args));
|
|
2441
|
+
emit({ type: "observation" /* OBSERVATION */, text: toolResult.substring(0, 200) });
|
|
2442
|
+
let resultMetadata;
|
|
2443
|
+
const uploadBaseUrl = getUploadBaseUrl();
|
|
2444
|
+
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2445
|
+
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2446
|
+
const uploadedRefs = [];
|
|
2447
|
+
for (const file of this.pendingFlaggedFiles) {
|
|
2448
|
+
const filename = path5.basename(file.originalPath);
|
|
2449
|
+
const safeName = encodeURIComponent(filename);
|
|
2450
|
+
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2451
|
+
uploadedRefs.push({
|
|
2452
|
+
original_path: file.originalPath,
|
|
2453
|
+
reason: file.reason ?? "",
|
|
2454
|
+
storage_path: storagePath,
|
|
2455
|
+
file_size_bytes: file.data.length
|
|
2443
2456
|
});
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
case "session_config" /* SESSION_CONFIG */:
|
|
2448
|
-
uploadBaseUrl = msg.metadata?.["upload_url"];
|
|
2449
|
-
break;
|
|
2450
|
-
case "ping" /* PING */: {
|
|
2451
|
-
const pongMsg = { type: "pong" /* PONG */ };
|
|
2452
|
-
try {
|
|
2453
|
-
ws.send(JSON.stringify(pongMsg));
|
|
2454
|
-
} catch {
|
|
2455
|
-
}
|
|
2456
|
-
break;
|
|
2457
|
+
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2458
|
+
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2459
|
+
void _PRBEAgent.backgroundUpload(file.data, uploadUrl, this.config.apiKey, contentType, this.getFetchSignal());
|
|
2457
2460
|
}
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
case "tool_result" /* TOOL_RESULT */:
|
|
2461
|
-
case "upload_request" /* UPLOAD_REQUEST */:
|
|
2462
|
-
case "cancel" /* CANCEL */:
|
|
2463
|
-
case "pong" /* PONG */:
|
|
2464
|
-
case "upload_url" /* UPLOAD_URL */:
|
|
2465
|
-
break;
|
|
2461
|
+
resultMetadata = { flagged_files: uploadedRefs };
|
|
2462
|
+
this.pendingFlaggedFiles = [];
|
|
2466
2463
|
}
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2464
|
+
conn.sendToolResult(callId, toolName, toolResult, resultMetadata);
|
|
2465
|
+
break;
|
|
2466
|
+
}
|
|
2467
|
+
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2468
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: msg.name ?? "", label: msg.content ?? "" });
|
|
2469
|
+
break;
|
|
2470
|
+
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2471
|
+
emit({ type: "observation" /* OBSERVATION */, text: (msg.content ?? "").substring(0, 200) });
|
|
2472
|
+
break;
|
|
2473
|
+
case "complete" /* COMPLETE */: {
|
|
2474
|
+
const report = msg.content ?? "";
|
|
2475
|
+
const completedTicketId = msg.metadata?.["ticket_id"];
|
|
2476
|
+
const sessionId = msg.metadata?.["session_id"];
|
|
2477
|
+
emit({ type: "completed" /* COMPLETED */, report, ticketId: completedTicketId });
|
|
2478
|
+
conn.close(1e3, "Complete");
|
|
2479
|
+
finish({ report, ticketId: completedTicketId, sessionId });
|
|
2480
|
+
break;
|
|
2481
|
+
}
|
|
2482
|
+
case "error" /* ERROR */:
|
|
2483
|
+
emit({ type: "error" /* ERROR */, message: msg.content || "Unknown error" });
|
|
2484
|
+
conn.close(1e3, "Error received");
|
|
2476
2485
|
finish(null);
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
});
|
|
2487
|
-
finish(null);
|
|
2488
|
-
}
|
|
2486
|
+
break;
|
|
2487
|
+
case "session_config" /* SESSION_CONFIG */:
|
|
2488
|
+
setUploadBaseUrl(msg.metadata?.["upload_url"]);
|
|
2489
|
+
break;
|
|
2490
|
+
case "conversation_update" /* CONVERSATION_UPDATE */: {
|
|
2491
|
+
try {
|
|
2492
|
+
const entry = JSON.parse(msg.content ?? "{}");
|
|
2493
|
+
this.state.appendConversation(entry);
|
|
2494
|
+
} catch {
|
|
2489
2495
|
}
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
} catch {
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
case "ping" /* PING */:
|
|
2499
|
+
conn.sendPong();
|
|
2500
|
+
break;
|
|
2501
|
+
default:
|
|
2502
|
+
break;
|
|
2498
2503
|
}
|
|
2499
2504
|
}
|
|
2500
2505
|
extractArgs(metadata) {
|
|
@@ -2612,6 +2617,7 @@ var DEFAULT_PRBE_STATE = {
|
|
|
2612
2617
|
summary: "",
|
|
2613
2618
|
currentQuery: "",
|
|
2614
2619
|
resolvedInteractions: [],
|
|
2620
|
+
conversationHistory: [],
|
|
2615
2621
|
completedInvestigations: [],
|
|
2616
2622
|
activeCRs: [],
|
|
2617
2623
|
completedCRs: [],
|
|
@@ -2649,6 +2655,7 @@ function serializePRBEState(state) {
|
|
|
2649
2655
|
pendingInteraction: state.pendingInteraction,
|
|
2650
2656
|
resolvedInteractions: state.resolvedInteractions,
|
|
2651
2657
|
agentMessage: state.agentMessage,
|
|
2658
|
+
conversationHistory: state.conversationHistory,
|
|
2652
2659
|
completedInvestigations: state.completedInvestigations.map((inv) => ({
|
|
2653
2660
|
id: inv.id,
|
|
2654
2661
|
query: inv.query,
|
|
@@ -2657,6 +2664,7 @@ function serializePRBEState(state) {
|
|
|
2657
2664
|
ticketId: inv.ticketId,
|
|
2658
2665
|
events: inv.events,
|
|
2659
2666
|
resolvedInteractions: inv.resolvedInteractions,
|
|
2667
|
+
conversationHistory: inv.conversationHistory,
|
|
2660
2668
|
completedAt: inv.completedAt.toISOString()
|
|
2661
2669
|
})),
|
|
2662
2670
|
activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
|
|
@@ -2678,6 +2686,7 @@ export {
|
|
|
2678
2686
|
AskUserTool,
|
|
2679
2687
|
BashExecuteTool,
|
|
2680
2688
|
ClearAppLogsTool,
|
|
2689
|
+
ConversationRole,
|
|
2681
2690
|
DEFAULT_PRBE_STATE,
|
|
2682
2691
|
FindFilesTool,
|
|
2683
2692
|
FlagAppLogsTool,
|