@prbe.ai/electron-sdk 0.1.13 → 0.1.15
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 +13 -4
- package/dist/index.d.ts +13 -4
- package/dist/index.js +249 -226
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +248 -226
- package/dist/index.mjs.map +1 -1
- package/dist/{types-B_KS1-FJ.d.mts → types-Cyfgy1uD.d.mts} +31 -12
- package/dist/{types-B_KS1-FJ.d.ts → types-Cyfgy1uD.d.ts} +31 -12
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -1
- package/dist/types.mjs +4 -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";
|
|
@@ -55,6 +62,7 @@ var PRBEAgentConfigKey = /* @__PURE__ */ ((PRBEAgentConfigKey3) => {
|
|
|
55
62
|
PRBEAgentConfigKey3["IPC_MAIN"] = "ipcMain";
|
|
56
63
|
PRBEAgentConfigKey3["RENDERER_LOG_CHANNEL"] = "rendererLogChannel";
|
|
57
64
|
PRBEAgentConfigKey3["APP_DATA_PATH"] = "appDataPath";
|
|
65
|
+
PRBEAgentConfigKey3["SESSION_METADATA"] = "sessionMetadata";
|
|
58
66
|
return PRBEAgentConfigKey3;
|
|
59
67
|
})(PRBEAgentConfigKey || {});
|
|
60
68
|
var PRBEAgentStatusType = /* @__PURE__ */ ((PRBEAgentStatusType2) => {
|
|
@@ -91,6 +99,83 @@ function redactPII(text) {
|
|
|
91
99
|
var API_URL = "https://api.prbe.ai";
|
|
92
100
|
var MIDDLEWARE_URL = "wss://middleware.prbe.ai";
|
|
93
101
|
|
|
102
|
+
// src/connection.ts
|
|
103
|
+
var InvestigationConnection = class {
|
|
104
|
+
constructor(url, apiKey, onMessage, onError, onClose) {
|
|
105
|
+
this.onMessage = onMessage;
|
|
106
|
+
this.onError = onError;
|
|
107
|
+
this.onClose = onClose;
|
|
108
|
+
this.ws = new WebSocket(url, {
|
|
109
|
+
headers: { "X-API-Key": apiKey }
|
|
110
|
+
});
|
|
111
|
+
this.ws.onmessage = (event) => {
|
|
112
|
+
const raw = typeof event.data === "string" ? event.data : event.data instanceof Buffer ? event.data.toString("utf-8") : null;
|
|
113
|
+
if (!raw) return;
|
|
114
|
+
try {
|
|
115
|
+
const msg = JSON.parse(raw);
|
|
116
|
+
this.onMessage(msg);
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.ws.onerror = (event) => {
|
|
121
|
+
const errorEvent = event;
|
|
122
|
+
this.onError(errorEvent.message || "WebSocket connection error");
|
|
123
|
+
};
|
|
124
|
+
this.ws.onclose = () => {
|
|
125
|
+
this.onClose();
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
ws;
|
|
129
|
+
closed = false;
|
|
130
|
+
get isOpen() {
|
|
131
|
+
return !this.closed && this.ws.readyState === WebSocket.OPEN;
|
|
132
|
+
}
|
|
133
|
+
send(msg) {
|
|
134
|
+
if (!this.isOpen) return false;
|
|
135
|
+
try {
|
|
136
|
+
this.ws.send(JSON.stringify(msg));
|
|
137
|
+
return true;
|
|
138
|
+
} catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
sendConversationMessage(content) {
|
|
143
|
+
this.send({
|
|
144
|
+
type: "conversation_message" /* CONVERSATION_MESSAGE */,
|
|
145
|
+
content
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
sendToolResult(callId, toolName, result, metadata) {
|
|
149
|
+
this.send({
|
|
150
|
+
type: "tool_result" /* TOOL_RESULT */,
|
|
151
|
+
id: callId,
|
|
152
|
+
name: toolName,
|
|
153
|
+
content: result,
|
|
154
|
+
metadata
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
sendCancel() {
|
|
158
|
+
this.send({ type: "cancel" /* CANCEL */ });
|
|
159
|
+
}
|
|
160
|
+
sendPong() {
|
|
161
|
+
this.send({ type: "pong" /* PONG */ });
|
|
162
|
+
}
|
|
163
|
+
close(code = 1e3, reason) {
|
|
164
|
+
if (this.closed) return;
|
|
165
|
+
this.closed = true;
|
|
166
|
+
try {
|
|
167
|
+
this.ws.close(code, reason);
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Set the onopen handler. Called when the connection is ready to send messages.
|
|
173
|
+
*/
|
|
174
|
+
set onopen(handler) {
|
|
175
|
+
this.ws.onopen = handler;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
94
179
|
// src/state.ts
|
|
95
180
|
import { EventEmitter } from "events";
|
|
96
181
|
import { randomUUID } from "crypto";
|
|
@@ -119,6 +204,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
119
204
|
pendingInteraction;
|
|
120
205
|
resolvedInteractions = [];
|
|
121
206
|
agentMessage;
|
|
207
|
+
conversationHistory = [];
|
|
122
208
|
// Completed user investigations (history)
|
|
123
209
|
completedInvestigations = [];
|
|
124
210
|
// Background context requests
|
|
@@ -142,6 +228,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
142
228
|
this.isInvestigating = true;
|
|
143
229
|
this.events = [];
|
|
144
230
|
this.resolvedInteractions = [];
|
|
231
|
+
this.conversationHistory = [];
|
|
145
232
|
this.report = "";
|
|
146
233
|
this.summary = "";
|
|
147
234
|
this.currentQuery = query;
|
|
@@ -149,10 +236,15 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
149
236
|
this.agentMessage = void 0;
|
|
150
237
|
this.emit("status" /* STATUS */);
|
|
151
238
|
}
|
|
239
|
+
appendConversation(entry) {
|
|
240
|
+
this.conversationHistory.push(entry);
|
|
241
|
+
this.emit("status" /* STATUS */);
|
|
242
|
+
}
|
|
152
243
|
resetInvestigation() {
|
|
153
244
|
this.isInvestigating = false;
|
|
154
245
|
this.events = [];
|
|
155
246
|
this.resolvedInteractions = [];
|
|
247
|
+
this.conversationHistory = [];
|
|
156
248
|
this.report = "";
|
|
157
249
|
this.summary = "";
|
|
158
250
|
this.currentQuery = "";
|
|
@@ -185,7 +277,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
185
277
|
this.emit("status" /* STATUS */);
|
|
186
278
|
}
|
|
187
279
|
}
|
|
188
|
-
completeInvestigation(report,
|
|
280
|
+
completeInvestigation(report, ticketId) {
|
|
189
281
|
if (this.events.length > 0) {
|
|
190
282
|
this.events[this.events.length - 1].isCompleted = true;
|
|
191
283
|
}
|
|
@@ -194,16 +286,15 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
194
286
|
id: randomUUID(),
|
|
195
287
|
query: this.currentQuery,
|
|
196
288
|
report,
|
|
197
|
-
summary,
|
|
198
289
|
ticketId,
|
|
199
290
|
events: [...this.events],
|
|
200
291
|
resolvedInteractions: [...this.resolvedInteractions],
|
|
292
|
+
conversationHistory: [...this.conversationHistory],
|
|
201
293
|
completedAt: /* @__PURE__ */ new Date()
|
|
202
294
|
});
|
|
203
295
|
this.report = report;
|
|
204
|
-
this.summary = summary;
|
|
205
296
|
this.isInvestigating = false;
|
|
206
|
-
this.emit("complete" /* COMPLETE */, { report
|
|
297
|
+
this.emit("complete" /* COMPLETE */, { report });
|
|
207
298
|
this.emit("status" /* STATUS */);
|
|
208
299
|
}
|
|
209
300
|
failInvestigation(message) {
|
|
@@ -328,7 +419,7 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
328
419
|
cr.events[cr.events.length - 1].detail = text;
|
|
329
420
|
this.emit("status" /* STATUS */);
|
|
330
421
|
}
|
|
331
|
-
completeCR(id, report
|
|
422
|
+
completeCR(id, report) {
|
|
332
423
|
const cr = this.activeCRs.get(id);
|
|
333
424
|
if (!cr) return;
|
|
334
425
|
this.activeCRs.delete(id);
|
|
@@ -344,7 +435,6 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
344
435
|
cr.isRunning = false;
|
|
345
436
|
cr.isCompleted = true;
|
|
346
437
|
cr.report = report;
|
|
347
|
-
cr.summary = summary;
|
|
348
438
|
this.completedCRs.unshift(cr);
|
|
349
439
|
this.emit("cr-complete" /* CR_COMPLETE */, cr);
|
|
350
440
|
this.emit("status" /* STATUS */);
|
|
@@ -1281,9 +1371,9 @@ var AskUserTool = class {
|
|
|
1281
1371
|
required: true
|
|
1282
1372
|
},
|
|
1283
1373
|
{
|
|
1284
|
-
name: "
|
|
1374
|
+
name: "reason",
|
|
1285
1375
|
type: "STRING" /* STRING */,
|
|
1286
|
-
description: "
|
|
1376
|
+
description: "Short reason displayed alongside the input prompt explaining why you need this information",
|
|
1287
1377
|
required: false
|
|
1288
1378
|
}
|
|
1289
1379
|
]
|
|
@@ -1295,12 +1385,11 @@ var AskUserTool = class {
|
|
|
1295
1385
|
if (this.requester.investigationSource !== "user" /* USER */) {
|
|
1296
1386
|
return "This is a context request investigation \u2014 you cannot ask the user questions. Use the available tools to answer the query autonomously.";
|
|
1297
1387
|
}
|
|
1298
|
-
const
|
|
1388
|
+
const reason = args["reason"] ?? "Waiting for your response";
|
|
1299
1389
|
const response = await this.requester.requestUserInteraction({
|
|
1300
1390
|
type: "ask_question" /* ASK_QUESTION */,
|
|
1301
1391
|
interactionId: randomUUID3(),
|
|
1302
|
-
question
|
|
1303
|
-
context
|
|
1392
|
+
question: reason
|
|
1304
1393
|
});
|
|
1305
1394
|
const askResponse = response;
|
|
1306
1395
|
return askResponse.answer;
|
|
@@ -1721,6 +1810,7 @@ var HistoryStore = class {
|
|
|
1721
1810
|
ticketId: inv.ticketId,
|
|
1722
1811
|
events: inv.events,
|
|
1723
1812
|
resolvedInteractions: inv.resolvedInteractions,
|
|
1813
|
+
conversationHistory: inv.conversationHistory,
|
|
1724
1814
|
completedAt: inv.completedAt.toISOString()
|
|
1725
1815
|
};
|
|
1726
1816
|
fs2.writeFileSync(
|
|
@@ -1809,11 +1899,12 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1809
1899
|
logCapture;
|
|
1810
1900
|
config;
|
|
1811
1901
|
appDataPath;
|
|
1902
|
+
sessionMetadata;
|
|
1812
1903
|
interactionHandler;
|
|
1813
1904
|
registry = new PRBEToolRegistry();
|
|
1814
1905
|
grantedPaths = /* @__PURE__ */ new Set();
|
|
1815
1906
|
userCancelled = false;
|
|
1816
|
-
|
|
1907
|
+
activeConnection = null;
|
|
1817
1908
|
pollingTimer = null;
|
|
1818
1909
|
persistedData;
|
|
1819
1910
|
fetchAbortController = null;
|
|
@@ -1868,6 +1959,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1868
1959
|
};
|
|
1869
1960
|
this.interactionHandler = config.interactionHandler;
|
|
1870
1961
|
this.appDataPath = config.appDataPath;
|
|
1962
|
+
this.sessionMetadata = config.sessionMetadata ?? {};
|
|
1871
1963
|
if (this.appDataPath && !this.config.autoApprovedDirs.includes(this.appDataPath)) {
|
|
1872
1964
|
this.config.autoApprovedDirs.push(this.appDataPath);
|
|
1873
1965
|
}
|
|
@@ -1973,6 +2065,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1973
2065
|
get investigationSource() {
|
|
1974
2066
|
return this.currentInvestigationSource;
|
|
1975
2067
|
}
|
|
2068
|
+
sendConversationMessage(content) {
|
|
2069
|
+
this.activeConnection?.sendConversationMessage(content);
|
|
2070
|
+
}
|
|
1976
2071
|
async requestUserInteraction(payload) {
|
|
1977
2072
|
if (!this.interactionHandler) {
|
|
1978
2073
|
throw new PRBEAgentError(
|
|
@@ -1992,6 +2087,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1992
2087
|
} else {
|
|
1993
2088
|
this.state.resolveInteraction(response);
|
|
1994
2089
|
}
|
|
2090
|
+
if (response.type === "request_permission" /* REQUEST_PERMISSION */) {
|
|
2091
|
+
const approved = response.approved;
|
|
2092
|
+
this.sendConversationMessage(approved ? "Approved" : "Denied");
|
|
2093
|
+
} else if (response.type === "request_path_access" /* REQUEST_PATH_ACCESS */) {
|
|
2094
|
+
const granted = response.granted;
|
|
2095
|
+
this.sendConversationMessage(granted ? "Allowed" : "Denied");
|
|
2096
|
+
}
|
|
1995
2097
|
return response;
|
|
1996
2098
|
} catch (err) {
|
|
1997
2099
|
if (this.currentInvestigationSource === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
|
|
@@ -2011,6 +2113,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2011
2113
|
}
|
|
2012
2114
|
}
|
|
2013
2115
|
// ---------- Public API ----------
|
|
2116
|
+
/**
|
|
2117
|
+
* Update session metadata. Merged with existing metadata.
|
|
2118
|
+
* Call this to add user profile data, app version, etc. after async initialization.
|
|
2119
|
+
*/
|
|
2120
|
+
updateSessionMetadata(metadata) {
|
|
2121
|
+
this.sessionMetadata = { ...this.sessionMetadata, ...metadata };
|
|
2122
|
+
}
|
|
2014
2123
|
/**
|
|
2015
2124
|
* Register a custom tool that the middleware can invoke during investigations.
|
|
2016
2125
|
*/
|
|
@@ -2044,7 +2153,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2044
2153
|
this.state.appendEvent("Thinking", status.text);
|
|
2045
2154
|
break;
|
|
2046
2155
|
case "completed" /* COMPLETED */:
|
|
2047
|
-
this.state.completeInvestigation(status.report, status.
|
|
2156
|
+
this.state.completeInvestigation(status.report, status.ticketId);
|
|
2048
2157
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2049
2158
|
break;
|
|
2050
2159
|
case "error" /* ERROR */:
|
|
@@ -2074,9 +2183,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2074
2183
|
*/
|
|
2075
2184
|
cancelInvestigation() {
|
|
2076
2185
|
this.userCancelled = true;
|
|
2077
|
-
if (this.
|
|
2078
|
-
this.
|
|
2079
|
-
this.
|
|
2186
|
+
if (this.activeConnection) {
|
|
2187
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2188
|
+
this.activeConnection = null;
|
|
2080
2189
|
}
|
|
2081
2190
|
}
|
|
2082
2191
|
/**
|
|
@@ -2084,9 +2193,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2084
2193
|
*/
|
|
2085
2194
|
cancel() {
|
|
2086
2195
|
this.userCancelled = true;
|
|
2087
|
-
if (this.
|
|
2088
|
-
this.
|
|
2089
|
-
this.
|
|
2196
|
+
if (this.activeConnection) {
|
|
2197
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2198
|
+
this.activeConnection = null;
|
|
2090
2199
|
}
|
|
2091
2200
|
this.abortInFlightRequests();
|
|
2092
2201
|
this.stopPolling();
|
|
@@ -2225,7 +2334,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2225
2334
|
this.state.appendCREvent(crID, "Thinking", status.text);
|
|
2226
2335
|
break;
|
|
2227
2336
|
case "completed" /* COMPLETED */:
|
|
2228
|
-
this.state.completeCR(crID, status.report
|
|
2337
|
+
this.state.completeCR(crID, status.report);
|
|
2229
2338
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2230
2339
|
break;
|
|
2231
2340
|
case "error" /* ERROR */:
|
|
@@ -2252,31 +2361,44 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2252
2361
|
connectToProxy(query, contextRequestID, emit, isCancelled, ticketId) {
|
|
2253
2362
|
return new Promise((resolve2) => {
|
|
2254
2363
|
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
2364
|
let uploadBaseUrl;
|
|
2272
2365
|
let resolved = false;
|
|
2273
2366
|
const finish = (result) => {
|
|
2274
2367
|
if (resolved) return;
|
|
2275
2368
|
resolved = true;
|
|
2276
|
-
this.
|
|
2369
|
+
this.activeConnection = null;
|
|
2277
2370
|
resolve2(result);
|
|
2278
2371
|
};
|
|
2279
|
-
|
|
2372
|
+
let conn;
|
|
2373
|
+
try {
|
|
2374
|
+
conn = new InvestigationConnection(
|
|
2375
|
+
wsUrl,
|
|
2376
|
+
this.config.apiKey,
|
|
2377
|
+
(msg) => this.handleMessage(msg, conn, emit, isCancelled, finish, () => uploadBaseUrl, (url) => {
|
|
2378
|
+
uploadBaseUrl = url;
|
|
2379
|
+
}),
|
|
2380
|
+
(message) => {
|
|
2381
|
+
if (!isCancelled()) emit({ type: "error" /* ERROR */, message });
|
|
2382
|
+
finish(null);
|
|
2383
|
+
},
|
|
2384
|
+
() => {
|
|
2385
|
+
if (!resolved) {
|
|
2386
|
+
if (isCancelled()) {
|
|
2387
|
+
finish(null);
|
|
2388
|
+
} else {
|
|
2389
|
+
emit({ type: "error" /* ERROR */, message: "WebSocket connection closed unexpectedly" });
|
|
2390
|
+
finish(null);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
);
|
|
2395
|
+
} catch (err) {
|
|
2396
|
+
emit({ type: "error" /* ERROR */, message: `Failed to create WebSocket: ${err}` });
|
|
2397
|
+
resolve2(null);
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2400
|
+
this.activeConnection = conn;
|
|
2401
|
+
conn.onopen = () => {
|
|
2280
2402
|
const toolDeclarations = this.registry.allDeclarations().map((decl) => ({
|
|
2281
2403
|
name: decl.name,
|
|
2282
2404
|
description: decl.description,
|
|
@@ -2295,206 +2417,102 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2295
2417
|
os_version: os2.release(),
|
|
2296
2418
|
arch: os2.arch()
|
|
2297
2419
|
};
|
|
2298
|
-
if (contextRequestID)
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
if (
|
|
2302
|
-
startMetadata["
|
|
2420
|
+
if (contextRequestID) startMetadata["context_request_id"] = contextRequestID;
|
|
2421
|
+
if (ticketId) startMetadata["ticket_id"] = ticketId;
|
|
2422
|
+
if (this.appDataPath) startMetadata["app_data_path"] = this.appDataPath;
|
|
2423
|
+
if (Object.keys(this.sessionMetadata).length > 0) {
|
|
2424
|
+
startMetadata["session_metadata"] = this.sessionMetadata;
|
|
2303
2425
|
}
|
|
2304
|
-
if (
|
|
2305
|
-
|
|
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
|
-
});
|
|
2426
|
+
if (!conn.send({ type: "start" /* START */, content: query, metadata: startMetadata })) {
|
|
2427
|
+
emit({ type: "error" /* ERROR */, message: "Failed to send start message" });
|
|
2319
2428
|
finish(null);
|
|
2320
2429
|
return;
|
|
2321
2430
|
}
|
|
2322
2431
|
emit({ type: "started" /* STARTED */ });
|
|
2323
2432
|
this.pendingFlaggedFiles = [];
|
|
2324
2433
|
};
|
|
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"
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
async handleMessage(msg, conn, emit, isCancelled, finish, getUploadBaseUrl, setUploadBaseUrl) {
|
|
2437
|
+
if (isCancelled()) {
|
|
2438
|
+
conn.sendCancel();
|
|
2439
|
+
conn.close(1e3, "Cancelled");
|
|
2440
|
+
finish(null);
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
switch (msg.type) {
|
|
2444
|
+
case "thought" /* THOUGHT */:
|
|
2445
|
+
emit({ type: "thought" /* THOUGHT */, text: msg.content ?? "" });
|
|
2446
|
+
break;
|
|
2447
|
+
case "tool_call" /* TOOL_CALL */: {
|
|
2448
|
+
const toolName = msg.name ?? "";
|
|
2449
|
+
const callId = msg.id ?? "";
|
|
2450
|
+
const args = this.extractArgs(msg.metadata);
|
|
2451
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: toolName, label: msg.content ?? `Running ${toolName}` });
|
|
2452
|
+
this.pendingFlaggedFiles = [];
|
|
2453
|
+
const toolResult = redactPII(await this.registry.execute(toolName, args));
|
|
2454
|
+
emit({ type: "observation" /* OBSERVATION */, text: toolResult.substring(0, 200) });
|
|
2455
|
+
let resultMetadata;
|
|
2456
|
+
const uploadBaseUrl = getUploadBaseUrl();
|
|
2457
|
+
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2458
|
+
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2459
|
+
const uploadedRefs = [];
|
|
2460
|
+
for (const file of this.pendingFlaggedFiles) {
|
|
2461
|
+
const filename = path5.basename(file.originalPath);
|
|
2462
|
+
const safeName = encodeURIComponent(filename);
|
|
2463
|
+
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2464
|
+
uploadedRefs.push({
|
|
2465
|
+
original_path: file.originalPath,
|
|
2466
|
+
reason: file.reason ?? "",
|
|
2467
|
+
storage_path: storagePath,
|
|
2468
|
+
file_size_bytes: file.data.length
|
|
2443
2469
|
});
|
|
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;
|
|
2470
|
+
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2471
|
+
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2472
|
+
void _PRBEAgent.backgroundUpload(file.data, uploadUrl, this.config.apiKey, contentType, this.getFetchSignal());
|
|
2457
2473
|
}
|
|
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;
|
|
2474
|
+
resultMetadata = { flagged_files: uploadedRefs };
|
|
2475
|
+
this.pendingFlaggedFiles = [];
|
|
2466
2476
|
}
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2477
|
+
conn.sendToolResult(callId, toolName, toolResult, resultMetadata);
|
|
2478
|
+
break;
|
|
2479
|
+
}
|
|
2480
|
+
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2481
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: msg.name ?? "", label: msg.content ?? "" });
|
|
2482
|
+
break;
|
|
2483
|
+
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2484
|
+
emit({ type: "observation" /* OBSERVATION */, text: (msg.content ?? "").substring(0, 200) });
|
|
2485
|
+
break;
|
|
2486
|
+
case "complete" /* COMPLETE */: {
|
|
2487
|
+
const report = msg.content ?? "";
|
|
2488
|
+
const completedTicketId = msg.metadata?.["ticket_id"];
|
|
2489
|
+
const sessionId = msg.metadata?.["session_id"];
|
|
2490
|
+
emit({ type: "completed" /* COMPLETED */, report, ticketId: completedTicketId });
|
|
2491
|
+
conn.close(1e3, "Complete");
|
|
2492
|
+
finish({ report, ticketId: completedTicketId, sessionId });
|
|
2493
|
+
break;
|
|
2494
|
+
}
|
|
2495
|
+
case "error" /* ERROR */:
|
|
2496
|
+
emit({ type: "error" /* ERROR */, message: msg.content || "Unknown error" });
|
|
2497
|
+
conn.close(1e3, "Error received");
|
|
2476
2498
|
finish(null);
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
});
|
|
2487
|
-
finish(null);
|
|
2488
|
-
}
|
|
2499
|
+
break;
|
|
2500
|
+
case "session_config" /* SESSION_CONFIG */:
|
|
2501
|
+
setUploadBaseUrl(msg.metadata?.["upload_url"]);
|
|
2502
|
+
break;
|
|
2503
|
+
case "conversation_update" /* CONVERSATION_UPDATE */: {
|
|
2504
|
+
try {
|
|
2505
|
+
const entry = JSON.parse(msg.content ?? "{}");
|
|
2506
|
+
this.state.appendConversation(entry);
|
|
2507
|
+
} catch {
|
|
2489
2508
|
}
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
} catch {
|
|
2509
|
+
break;
|
|
2510
|
+
}
|
|
2511
|
+
case "ping" /* PING */:
|
|
2512
|
+
conn.sendPong();
|
|
2513
|
+
break;
|
|
2514
|
+
default:
|
|
2515
|
+
break;
|
|
2498
2516
|
}
|
|
2499
2517
|
}
|
|
2500
2518
|
extractArgs(metadata) {
|
|
@@ -2612,6 +2630,7 @@ var DEFAULT_PRBE_STATE = {
|
|
|
2612
2630
|
summary: "",
|
|
2613
2631
|
currentQuery: "",
|
|
2614
2632
|
resolvedInteractions: [],
|
|
2633
|
+
conversationHistory: [],
|
|
2615
2634
|
completedInvestigations: [],
|
|
2616
2635
|
activeCRs: [],
|
|
2617
2636
|
completedCRs: [],
|
|
@@ -2649,6 +2668,7 @@ function serializePRBEState(state) {
|
|
|
2649
2668
|
pendingInteraction: state.pendingInteraction,
|
|
2650
2669
|
resolvedInteractions: state.resolvedInteractions,
|
|
2651
2670
|
agentMessage: state.agentMessage,
|
|
2671
|
+
conversationHistory: state.conversationHistory,
|
|
2652
2672
|
completedInvestigations: state.completedInvestigations.map((inv) => ({
|
|
2653
2673
|
id: inv.id,
|
|
2654
2674
|
query: inv.query,
|
|
@@ -2657,6 +2677,7 @@ function serializePRBEState(state) {
|
|
|
2657
2677
|
ticketId: inv.ticketId,
|
|
2658
2678
|
events: inv.events,
|
|
2659
2679
|
resolvedInteractions: inv.resolvedInteractions,
|
|
2680
|
+
conversationHistory: inv.conversationHistory,
|
|
2660
2681
|
completedAt: inv.completedAt.toISOString()
|
|
2661
2682
|
})),
|
|
2662
2683
|
activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
|
|
@@ -2678,6 +2699,7 @@ export {
|
|
|
2678
2699
|
AskUserTool,
|
|
2679
2700
|
BashExecuteTool,
|
|
2680
2701
|
ClearAppLogsTool,
|
|
2702
|
+
ConversationRole,
|
|
2681
2703
|
DEFAULT_PRBE_STATE,
|
|
2682
2704
|
FindFilesTool,
|
|
2683
2705
|
FlagAppLogsTool,
|