@prbe.ai/electron-sdk 0.1.12 → 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 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +238 -250
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -250
- 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;
|
|
@@ -1841,13 +1930,6 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1841
1930
|
this.state.updateTrackedSessionIDs(ids);
|
|
1842
1931
|
this.syncPolling(ids.length > 0);
|
|
1843
1932
|
}
|
|
1844
|
-
get respondedCRIDs() {
|
|
1845
|
-
return new Set(this.persistedData.respondedCRIds ?? []);
|
|
1846
|
-
}
|
|
1847
|
-
set respondedCRIDs(ids) {
|
|
1848
|
-
this.persistedData.respondedCRIds = Array.from(ids);
|
|
1849
|
-
savePersistedData(this.persistedData);
|
|
1850
|
-
}
|
|
1851
1933
|
syncPolling(hasSessions) {
|
|
1852
1934
|
if (this.config.backgroundPolling && hasSessions) {
|
|
1853
1935
|
if (this.pollingTimer === null) {
|
|
@@ -1980,6 +2062,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1980
2062
|
get investigationSource() {
|
|
1981
2063
|
return this.currentInvestigationSource;
|
|
1982
2064
|
}
|
|
2065
|
+
sendConversationMessage(content) {
|
|
2066
|
+
this.activeConnection?.sendConversationMessage(content);
|
|
2067
|
+
}
|
|
1983
2068
|
async requestUserInteraction(payload) {
|
|
1984
2069
|
if (!this.interactionHandler) {
|
|
1985
2070
|
throw new PRBEAgentError(
|
|
@@ -1999,6 +2084,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1999
2084
|
} else {
|
|
2000
2085
|
this.state.resolveInteraction(response);
|
|
2001
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
|
+
}
|
|
2002
2094
|
return response;
|
|
2003
2095
|
} catch (err) {
|
|
2004
2096
|
if (this.currentInvestigationSource === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
|
|
@@ -2051,7 +2143,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2051
2143
|
this.state.appendEvent("Thinking", status.text);
|
|
2052
2144
|
break;
|
|
2053
2145
|
case "completed" /* COMPLETED */:
|
|
2054
|
-
this.state.completeInvestigation(status.report, status.
|
|
2146
|
+
this.state.completeInvestigation(status.report, status.ticketId);
|
|
2055
2147
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2056
2148
|
break;
|
|
2057
2149
|
case "error" /* ERROR */:
|
|
@@ -2081,9 +2173,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2081
2173
|
*/
|
|
2082
2174
|
cancelInvestigation() {
|
|
2083
2175
|
this.userCancelled = true;
|
|
2084
|
-
if (this.
|
|
2085
|
-
this.
|
|
2086
|
-
this.
|
|
2176
|
+
if (this.activeConnection) {
|
|
2177
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2178
|
+
this.activeConnection = null;
|
|
2087
2179
|
}
|
|
2088
2180
|
}
|
|
2089
2181
|
/**
|
|
@@ -2091,9 +2183,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2091
2183
|
*/
|
|
2092
2184
|
cancel() {
|
|
2093
2185
|
this.userCancelled = true;
|
|
2094
|
-
if (this.
|
|
2095
|
-
this.
|
|
2096
|
-
this.
|
|
2186
|
+
if (this.activeConnection) {
|
|
2187
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2188
|
+
this.activeConnection = null;
|
|
2097
2189
|
}
|
|
2098
2190
|
this.abortInFlightRequests();
|
|
2099
2191
|
this.stopPolling();
|
|
@@ -2129,27 +2221,12 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2129
2221
|
"/api/agent/poll",
|
|
2130
2222
|
request
|
|
2131
2223
|
);
|
|
2132
|
-
const knownCRIDs = /* @__PURE__ */ new Set();
|
|
2133
2224
|
for (const ticket of response.tickets) {
|
|
2134
2225
|
for (const cr of ticket.context_requests) {
|
|
2135
|
-
|
|
2136
|
-
if (!cr.is_active || this.respondedCRIDs.has(cr.id)) continue;
|
|
2226
|
+
if (!cr.is_active) continue;
|
|
2137
2227
|
await this.investigateForCR(cr, ticket.ticket_id);
|
|
2138
|
-
const ids = this.respondedCRIDs;
|
|
2139
|
-
ids.add(cr.id);
|
|
2140
|
-
this.respondedCRIDs = ids;
|
|
2141
2228
|
}
|
|
2142
2229
|
}
|
|
2143
|
-
const currentRespondedIDs = this.respondedCRIDs;
|
|
2144
|
-
const stale = new Set(
|
|
2145
|
-
[...currentRespondedIDs].filter((id) => !knownCRIDs.has(id))
|
|
2146
|
-
);
|
|
2147
|
-
if (stale.size > 0) {
|
|
2148
|
-
const pruned = new Set(
|
|
2149
|
-
[...currentRespondedIDs].filter((id) => !stale.has(id))
|
|
2150
|
-
);
|
|
2151
|
-
this.respondedCRIDs = pruned;
|
|
2152
|
-
}
|
|
2153
2230
|
return response;
|
|
2154
2231
|
} catch {
|
|
2155
2232
|
return null;
|
|
@@ -2247,7 +2324,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2247
2324
|
this.state.appendCREvent(crID, "Thinking", status.text);
|
|
2248
2325
|
break;
|
|
2249
2326
|
case "completed" /* COMPLETED */:
|
|
2250
|
-
this.state.completeCR(crID, status.report
|
|
2327
|
+
this.state.completeCR(crID, status.report);
|
|
2251
2328
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2252
2329
|
break;
|
|
2253
2330
|
case "error" /* ERROR */:
|
|
@@ -2274,31 +2351,44 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2274
2351
|
connectToProxy(query, contextRequestID, emit, isCancelled, ticketId) {
|
|
2275
2352
|
return new Promise((resolve2) => {
|
|
2276
2353
|
const wsUrl = `${MIDDLEWARE_URL}/api/agent/client/ws`;
|
|
2277
|
-
let ws;
|
|
2278
|
-
try {
|
|
2279
|
-
ws = new WebSocket(wsUrl, {
|
|
2280
|
-
headers: {
|
|
2281
|
-
"X-API-Key": this.config.apiKey
|
|
2282
|
-
}
|
|
2283
|
-
});
|
|
2284
|
-
} catch (err) {
|
|
2285
|
-
emit({
|
|
2286
|
-
type: "error" /* ERROR */,
|
|
2287
|
-
message: `Failed to create WebSocket: ${err}`
|
|
2288
|
-
});
|
|
2289
|
-
resolve2(null);
|
|
2290
|
-
return;
|
|
2291
|
-
}
|
|
2292
|
-
this.activeWS = ws;
|
|
2293
2354
|
let uploadBaseUrl;
|
|
2294
2355
|
let resolved = false;
|
|
2295
2356
|
const finish = (result) => {
|
|
2296
2357
|
if (resolved) return;
|
|
2297
2358
|
resolved = true;
|
|
2298
|
-
this.
|
|
2359
|
+
this.activeConnection = null;
|
|
2299
2360
|
resolve2(result);
|
|
2300
2361
|
};
|
|
2301
|
-
|
|
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 = () => {
|
|
2302
2392
|
const toolDeclarations = this.registry.allDeclarations().map((decl) => ({
|
|
2303
2393
|
name: decl.name,
|
|
2304
2394
|
description: decl.description,
|
|
@@ -2317,206 +2407,99 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2317
2407
|
os_version: os2.release(),
|
|
2318
2408
|
arch: os2.arch()
|
|
2319
2409
|
};
|
|
2320
|
-
if (contextRequestID)
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
if (
|
|
2324
|
-
|
|
2325
|
-
}
|
|
2326
|
-
if (this.appDataPath) {
|
|
2327
|
-
startMetadata["app_data_path"] = this.appDataPath;
|
|
2328
|
-
}
|
|
2329
|
-
const startMsg = {
|
|
2330
|
-
type: "start" /* START */,
|
|
2331
|
-
content: query,
|
|
2332
|
-
metadata: startMetadata
|
|
2333
|
-
};
|
|
2334
|
-
try {
|
|
2335
|
-
ws.send(JSON.stringify(startMsg));
|
|
2336
|
-
} catch (err) {
|
|
2337
|
-
emit({
|
|
2338
|
-
type: "error" /* ERROR */,
|
|
2339
|
-
message: `Failed to send start message: ${err}`
|
|
2340
|
-
});
|
|
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" });
|
|
2341
2415
|
finish(null);
|
|
2342
2416
|
return;
|
|
2343
2417
|
}
|
|
2344
2418
|
emit({ type: "started" /* STARTED */ });
|
|
2345
2419
|
this.pendingFlaggedFiles = [];
|
|
2346
2420
|
};
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
const
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
label: msg.content ?? `Running ${toolName}`
|
|
2383
|
-
});
|
|
2384
|
-
this.pendingFlaggedFiles = [];
|
|
2385
|
-
const toolResult = redactPII(
|
|
2386
|
-
await this.registry.execute(toolName, args)
|
|
2387
|
-
);
|
|
2388
|
-
emit({
|
|
2389
|
-
type: "observation" /* OBSERVATION */,
|
|
2390
|
-
text: toolResult.substring(0, 200)
|
|
2391
|
-
});
|
|
2392
|
-
let resultMetadata;
|
|
2393
|
-
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2394
|
-
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2395
|
-
const uploadedRefs = [];
|
|
2396
|
-
for (const file of this.pendingFlaggedFiles) {
|
|
2397
|
-
const filename = path5.basename(file.originalPath);
|
|
2398
|
-
const safeName = encodeURIComponent(filename);
|
|
2399
|
-
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2400
|
-
uploadedRefs.push({
|
|
2401
|
-
original_path: file.originalPath,
|
|
2402
|
-
reason: file.reason ?? "",
|
|
2403
|
-
storage_path: storagePath,
|
|
2404
|
-
file_size_bytes: file.data.length
|
|
2405
|
-
});
|
|
2406
|
-
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2407
|
-
const fileData = file.data;
|
|
2408
|
-
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2409
|
-
void _PRBEAgent.backgroundUpload(
|
|
2410
|
-
fileData,
|
|
2411
|
-
uploadUrl,
|
|
2412
|
-
this.config.apiKey,
|
|
2413
|
-
contentType,
|
|
2414
|
-
this.getFetchSignal()
|
|
2415
|
-
);
|
|
2416
|
-
}
|
|
2417
|
-
resultMetadata = { flagged_files: uploadedRefs };
|
|
2418
|
-
this.pendingFlaggedFiles = [];
|
|
2419
|
-
}
|
|
2420
|
-
const resultMsg = {
|
|
2421
|
-
type: "tool_result" /* TOOL_RESULT */,
|
|
2422
|
-
id: callId,
|
|
2423
|
-
name: toolName,
|
|
2424
|
-
content: toolResult,
|
|
2425
|
-
metadata: resultMetadata
|
|
2426
|
-
};
|
|
2427
|
-
try {
|
|
2428
|
-
ws.send(JSON.stringify(resultMsg));
|
|
2429
|
-
} catch {
|
|
2430
|
-
}
|
|
2431
|
-
break;
|
|
2432
|
-
}
|
|
2433
|
-
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2434
|
-
emit({
|
|
2435
|
-
type: "tool_call" /* TOOL_CALL */,
|
|
2436
|
-
name: msg.name ?? "",
|
|
2437
|
-
label: msg.content ?? ""
|
|
2438
|
-
});
|
|
2439
|
-
break;
|
|
2440
|
-
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2441
|
-
emit({
|
|
2442
|
-
type: "observation" /* OBSERVATION */,
|
|
2443
|
-
text: (msg.content ?? "").substring(0, 200)
|
|
2444
|
-
});
|
|
2445
|
-
break;
|
|
2446
|
-
case "complete" /* COMPLETE */: {
|
|
2447
|
-
const report = msg.content ?? "";
|
|
2448
|
-
const userSummary = msg.metadata?.["user_summary"] ?? "";
|
|
2449
|
-
const ticketId2 = msg.metadata?.["ticket_id"];
|
|
2450
|
-
const sessionId = msg.metadata?.["session_id"];
|
|
2451
|
-
emit({
|
|
2452
|
-
type: "completed" /* COMPLETED */,
|
|
2453
|
-
report,
|
|
2454
|
-
userSummary,
|
|
2455
|
-
ticketId: ticketId2
|
|
2456
|
-
});
|
|
2457
|
-
ws.close(1e3, "Complete");
|
|
2458
|
-
finish({ report, userSummary, ticketId: ticketId2, sessionId });
|
|
2459
|
-
break;
|
|
2460
|
-
}
|
|
2461
|
-
case "error" /* ERROR */:
|
|
2462
|
-
emit({
|
|
2463
|
-
type: "error" /* ERROR */,
|
|
2464
|
-
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
|
|
2465
2456
|
});
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
case "session_config" /* SESSION_CONFIG */:
|
|
2470
|
-
uploadBaseUrl = msg.metadata?.["upload_url"];
|
|
2471
|
-
break;
|
|
2472
|
-
case "ping" /* PING */: {
|
|
2473
|
-
const pongMsg = { type: "pong" /* PONG */ };
|
|
2474
|
-
try {
|
|
2475
|
-
ws.send(JSON.stringify(pongMsg));
|
|
2476
|
-
} catch {
|
|
2477
|
-
}
|
|
2478
|
-
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());
|
|
2479
2460
|
}
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
case "tool_result" /* TOOL_RESULT */:
|
|
2483
|
-
case "upload_request" /* UPLOAD_REQUEST */:
|
|
2484
|
-
case "cancel" /* CANCEL */:
|
|
2485
|
-
case "pong" /* PONG */:
|
|
2486
|
-
case "upload_url" /* UPLOAD_URL */:
|
|
2487
|
-
break;
|
|
2488
|
-
}
|
|
2489
|
-
};
|
|
2490
|
-
ws.onerror = (event) => {
|
|
2491
|
-
if (isCancelled()) {
|
|
2492
|
-
finish(null);
|
|
2493
|
-
return;
|
|
2461
|
+
resultMetadata = { flagged_files: uploadedRefs };
|
|
2462
|
+
this.pendingFlaggedFiles = [];
|
|
2494
2463
|
}
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
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");
|
|
2498
2485
|
finish(null);
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
});
|
|
2509
|
-
finish(null);
|
|
2510
|
-
}
|
|
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 {
|
|
2511
2495
|
}
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
} catch {
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
case "ping" /* PING */:
|
|
2499
|
+
conn.sendPong();
|
|
2500
|
+
break;
|
|
2501
|
+
default:
|
|
2502
|
+
break;
|
|
2520
2503
|
}
|
|
2521
2504
|
}
|
|
2522
2505
|
extractArgs(metadata) {
|
|
@@ -2634,6 +2617,7 @@ var DEFAULT_PRBE_STATE = {
|
|
|
2634
2617
|
summary: "",
|
|
2635
2618
|
currentQuery: "",
|
|
2636
2619
|
resolvedInteractions: [],
|
|
2620
|
+
conversationHistory: [],
|
|
2637
2621
|
completedInvestigations: [],
|
|
2638
2622
|
activeCRs: [],
|
|
2639
2623
|
completedCRs: [],
|
|
@@ -2671,6 +2655,7 @@ function serializePRBEState(state) {
|
|
|
2671
2655
|
pendingInteraction: state.pendingInteraction,
|
|
2672
2656
|
resolvedInteractions: state.resolvedInteractions,
|
|
2673
2657
|
agentMessage: state.agentMessage,
|
|
2658
|
+
conversationHistory: state.conversationHistory,
|
|
2674
2659
|
completedInvestigations: state.completedInvestigations.map((inv) => ({
|
|
2675
2660
|
id: inv.id,
|
|
2676
2661
|
query: inv.query,
|
|
@@ -2679,6 +2664,7 @@ function serializePRBEState(state) {
|
|
|
2679
2664
|
ticketId: inv.ticketId,
|
|
2680
2665
|
events: inv.events,
|
|
2681
2666
|
resolvedInteractions: inv.resolvedInteractions,
|
|
2667
|
+
conversationHistory: inv.conversationHistory,
|
|
2682
2668
|
completedAt: inv.completedAt.toISOString()
|
|
2683
2669
|
})),
|
|
2684
2670
|
activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
|
|
@@ -2700,6 +2686,7 @@ export {
|
|
|
2700
2686
|
AskUserTool,
|
|
2701
2687
|
BashExecuteTool,
|
|
2702
2688
|
ClearAppLogsTool,
|
|
2689
|
+
ConversationRole,
|
|
2703
2690
|
DEFAULT_PRBE_STATE,
|
|
2704
2691
|
FindFilesTool,
|
|
2705
2692
|
FlagAppLogsTool,
|