@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.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(src_exports, {
|
|
|
34
34
|
AskUserTool: () => AskUserTool,
|
|
35
35
|
BashExecuteTool: () => BashExecuteTool,
|
|
36
36
|
ClearAppLogsTool: () => ClearAppLogsTool,
|
|
37
|
+
ConversationRole: () => ConversationRole,
|
|
37
38
|
DEFAULT_PRBE_STATE: () => DEFAULT_PRBE_STATE,
|
|
38
39
|
FindFilesTool: () => FindFilesTool,
|
|
39
40
|
FlagAppLogsTool: () => FlagAppLogsTool,
|
|
@@ -79,6 +80,7 @@ var WSMessageType = /* @__PURE__ */ ((WSMessageType2) => {
|
|
|
79
80
|
WSMessageType2["START"] = "start";
|
|
80
81
|
WSMessageType2["TOOL_RESULT"] = "tool_result";
|
|
81
82
|
WSMessageType2["UPLOAD_REQUEST"] = "upload_request";
|
|
83
|
+
WSMessageType2["CONVERSATION_MESSAGE"] = "conversation_message";
|
|
82
84
|
WSMessageType2["CANCEL"] = "cancel";
|
|
83
85
|
WSMessageType2["PONG"] = "pong";
|
|
84
86
|
WSMessageType2["THOUGHT"] = "thought";
|
|
@@ -87,11 +89,17 @@ var WSMessageType = /* @__PURE__ */ ((WSMessageType2) => {
|
|
|
87
89
|
WSMessageType2["SERVER_OBSERVATION"] = "server_observation";
|
|
88
90
|
WSMessageType2["UPLOAD_URL"] = "upload_url";
|
|
89
91
|
WSMessageType2["SESSION_CONFIG"] = "session_config";
|
|
92
|
+
WSMessageType2["CONVERSATION_UPDATE"] = "conversation_update";
|
|
90
93
|
WSMessageType2["COMPLETE"] = "complete";
|
|
91
94
|
WSMessageType2["ERROR"] = "error";
|
|
92
95
|
WSMessageType2["PING"] = "ping";
|
|
93
96
|
return WSMessageType2;
|
|
94
97
|
})(WSMessageType || {});
|
|
98
|
+
var ConversationRole = /* @__PURE__ */ ((ConversationRole3) => {
|
|
99
|
+
ConversationRole3["User"] = "user";
|
|
100
|
+
ConversationRole3["Agent"] = "agent";
|
|
101
|
+
return ConversationRole3;
|
|
102
|
+
})(ConversationRole || {});
|
|
95
103
|
var ToolParamType = /* @__PURE__ */ ((ToolParamType2) => {
|
|
96
104
|
ToolParamType2["STRING"] = "STRING";
|
|
97
105
|
ToolParamType2["BOOLEAN"] = "BOOLEAN";
|
|
@@ -125,6 +133,7 @@ var PRBEAgentConfigKey = /* @__PURE__ */ ((PRBEAgentConfigKey3) => {
|
|
|
125
133
|
PRBEAgentConfigKey3["IPC_MAIN"] = "ipcMain";
|
|
126
134
|
PRBEAgentConfigKey3["RENDERER_LOG_CHANNEL"] = "rendererLogChannel";
|
|
127
135
|
PRBEAgentConfigKey3["APP_DATA_PATH"] = "appDataPath";
|
|
136
|
+
PRBEAgentConfigKey3["SESSION_METADATA"] = "sessionMetadata";
|
|
128
137
|
return PRBEAgentConfigKey3;
|
|
129
138
|
})(PRBEAgentConfigKey || {});
|
|
130
139
|
var PRBEAgentStatusType = /* @__PURE__ */ ((PRBEAgentStatusType2) => {
|
|
@@ -161,6 +170,83 @@ function redactPII(text) {
|
|
|
161
170
|
var API_URL = "https://api.prbe.ai";
|
|
162
171
|
var MIDDLEWARE_URL = "wss://middleware.prbe.ai";
|
|
163
172
|
|
|
173
|
+
// src/connection.ts
|
|
174
|
+
var InvestigationConnection = class {
|
|
175
|
+
constructor(url, apiKey, onMessage, onError, onClose) {
|
|
176
|
+
this.onMessage = onMessage;
|
|
177
|
+
this.onError = onError;
|
|
178
|
+
this.onClose = onClose;
|
|
179
|
+
this.ws = new WebSocket(url, {
|
|
180
|
+
headers: { "X-API-Key": apiKey }
|
|
181
|
+
});
|
|
182
|
+
this.ws.onmessage = (event) => {
|
|
183
|
+
const raw = typeof event.data === "string" ? event.data : event.data instanceof Buffer ? event.data.toString("utf-8") : null;
|
|
184
|
+
if (!raw) return;
|
|
185
|
+
try {
|
|
186
|
+
const msg = JSON.parse(raw);
|
|
187
|
+
this.onMessage(msg);
|
|
188
|
+
} catch {
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
this.ws.onerror = (event) => {
|
|
192
|
+
const errorEvent = event;
|
|
193
|
+
this.onError(errorEvent.message || "WebSocket connection error");
|
|
194
|
+
};
|
|
195
|
+
this.ws.onclose = () => {
|
|
196
|
+
this.onClose();
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
ws;
|
|
200
|
+
closed = false;
|
|
201
|
+
get isOpen() {
|
|
202
|
+
return !this.closed && this.ws.readyState === WebSocket.OPEN;
|
|
203
|
+
}
|
|
204
|
+
send(msg) {
|
|
205
|
+
if (!this.isOpen) return false;
|
|
206
|
+
try {
|
|
207
|
+
this.ws.send(JSON.stringify(msg));
|
|
208
|
+
return true;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
sendConversationMessage(content) {
|
|
214
|
+
this.send({
|
|
215
|
+
type: "conversation_message" /* CONVERSATION_MESSAGE */,
|
|
216
|
+
content
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
sendToolResult(callId, toolName, result, metadata) {
|
|
220
|
+
this.send({
|
|
221
|
+
type: "tool_result" /* TOOL_RESULT */,
|
|
222
|
+
id: callId,
|
|
223
|
+
name: toolName,
|
|
224
|
+
content: result,
|
|
225
|
+
metadata
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
sendCancel() {
|
|
229
|
+
this.send({ type: "cancel" /* CANCEL */ });
|
|
230
|
+
}
|
|
231
|
+
sendPong() {
|
|
232
|
+
this.send({ type: "pong" /* PONG */ });
|
|
233
|
+
}
|
|
234
|
+
close(code = 1e3, reason) {
|
|
235
|
+
if (this.closed) return;
|
|
236
|
+
this.closed = true;
|
|
237
|
+
try {
|
|
238
|
+
this.ws.close(code, reason);
|
|
239
|
+
} catch {
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Set the onopen handler. Called when the connection is ready to send messages.
|
|
244
|
+
*/
|
|
245
|
+
set onopen(handler) {
|
|
246
|
+
this.ws.onopen = handler;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
164
250
|
// src/state.ts
|
|
165
251
|
var import_events = require("events");
|
|
166
252
|
var import_crypto = require("crypto");
|
|
@@ -189,6 +275,7 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
189
275
|
pendingInteraction;
|
|
190
276
|
resolvedInteractions = [];
|
|
191
277
|
agentMessage;
|
|
278
|
+
conversationHistory = [];
|
|
192
279
|
// Completed user investigations (history)
|
|
193
280
|
completedInvestigations = [];
|
|
194
281
|
// Background context requests
|
|
@@ -212,6 +299,7 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
212
299
|
this.isInvestigating = true;
|
|
213
300
|
this.events = [];
|
|
214
301
|
this.resolvedInteractions = [];
|
|
302
|
+
this.conversationHistory = [];
|
|
215
303
|
this.report = "";
|
|
216
304
|
this.summary = "";
|
|
217
305
|
this.currentQuery = query;
|
|
@@ -219,10 +307,15 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
219
307
|
this.agentMessage = void 0;
|
|
220
308
|
this.emit("status" /* STATUS */);
|
|
221
309
|
}
|
|
310
|
+
appendConversation(entry) {
|
|
311
|
+
this.conversationHistory.push(entry);
|
|
312
|
+
this.emit("status" /* STATUS */);
|
|
313
|
+
}
|
|
222
314
|
resetInvestigation() {
|
|
223
315
|
this.isInvestigating = false;
|
|
224
316
|
this.events = [];
|
|
225
317
|
this.resolvedInteractions = [];
|
|
318
|
+
this.conversationHistory = [];
|
|
226
319
|
this.report = "";
|
|
227
320
|
this.summary = "";
|
|
228
321
|
this.currentQuery = "";
|
|
@@ -255,7 +348,7 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
255
348
|
this.emit("status" /* STATUS */);
|
|
256
349
|
}
|
|
257
350
|
}
|
|
258
|
-
completeInvestigation(report,
|
|
351
|
+
completeInvestigation(report, ticketId) {
|
|
259
352
|
if (this.events.length > 0) {
|
|
260
353
|
this.events[this.events.length - 1].isCompleted = true;
|
|
261
354
|
}
|
|
@@ -264,16 +357,15 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
264
357
|
id: (0, import_crypto.randomUUID)(),
|
|
265
358
|
query: this.currentQuery,
|
|
266
359
|
report,
|
|
267
|
-
summary,
|
|
268
360
|
ticketId,
|
|
269
361
|
events: [...this.events],
|
|
270
362
|
resolvedInteractions: [...this.resolvedInteractions],
|
|
363
|
+
conversationHistory: [...this.conversationHistory],
|
|
271
364
|
completedAt: /* @__PURE__ */ new Date()
|
|
272
365
|
});
|
|
273
366
|
this.report = report;
|
|
274
|
-
this.summary = summary;
|
|
275
367
|
this.isInvestigating = false;
|
|
276
|
-
this.emit("complete" /* COMPLETE */, { report
|
|
368
|
+
this.emit("complete" /* COMPLETE */, { report });
|
|
277
369
|
this.emit("status" /* STATUS */);
|
|
278
370
|
}
|
|
279
371
|
failInvestigation(message) {
|
|
@@ -398,7 +490,7 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
398
490
|
cr.events[cr.events.length - 1].detail = text;
|
|
399
491
|
this.emit("status" /* STATUS */);
|
|
400
492
|
}
|
|
401
|
-
completeCR(id, report
|
|
493
|
+
completeCR(id, report) {
|
|
402
494
|
const cr = this.activeCRs.get(id);
|
|
403
495
|
if (!cr) return;
|
|
404
496
|
this.activeCRs.delete(id);
|
|
@@ -414,7 +506,6 @@ var PRBEAgentState = class extends import_events.EventEmitter {
|
|
|
414
506
|
cr.isRunning = false;
|
|
415
507
|
cr.isCompleted = true;
|
|
416
508
|
cr.report = report;
|
|
417
|
-
cr.summary = summary;
|
|
418
509
|
this.completedCRs.unshift(cr);
|
|
419
510
|
this.emit("cr-complete" /* CR_COMPLETE */, cr);
|
|
420
511
|
this.emit("status" /* STATUS */);
|
|
@@ -1351,9 +1442,9 @@ var AskUserTool = class {
|
|
|
1351
1442
|
required: true
|
|
1352
1443
|
},
|
|
1353
1444
|
{
|
|
1354
|
-
name: "
|
|
1445
|
+
name: "reason",
|
|
1355
1446
|
type: "STRING" /* STRING */,
|
|
1356
|
-
description: "
|
|
1447
|
+
description: "Short reason displayed alongside the input prompt explaining why you need this information",
|
|
1357
1448
|
required: false
|
|
1358
1449
|
}
|
|
1359
1450
|
]
|
|
@@ -1365,12 +1456,11 @@ var AskUserTool = class {
|
|
|
1365
1456
|
if (this.requester.investigationSource !== "user" /* USER */) {
|
|
1366
1457
|
return "This is a context request investigation \u2014 you cannot ask the user questions. Use the available tools to answer the query autonomously.";
|
|
1367
1458
|
}
|
|
1368
|
-
const
|
|
1459
|
+
const reason = args["reason"] ?? "Waiting for your response";
|
|
1369
1460
|
const response = await this.requester.requestUserInteraction({
|
|
1370
1461
|
type: "ask_question" /* ASK_QUESTION */,
|
|
1371
1462
|
interactionId: (0, import_crypto3.randomUUID)(),
|
|
1372
|
-
question
|
|
1373
|
-
context
|
|
1463
|
+
question: reason
|
|
1374
1464
|
});
|
|
1375
1465
|
const askResponse = response;
|
|
1376
1466
|
return askResponse.answer;
|
|
@@ -1791,6 +1881,7 @@ var HistoryStore = class {
|
|
|
1791
1881
|
ticketId: inv.ticketId,
|
|
1792
1882
|
events: inv.events,
|
|
1793
1883
|
resolvedInteractions: inv.resolvedInteractions,
|
|
1884
|
+
conversationHistory: inv.conversationHistory,
|
|
1794
1885
|
completedAt: inv.completedAt.toISOString()
|
|
1795
1886
|
};
|
|
1796
1887
|
fs2.writeFileSync(
|
|
@@ -1879,11 +1970,12 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1879
1970
|
logCapture;
|
|
1880
1971
|
config;
|
|
1881
1972
|
appDataPath;
|
|
1973
|
+
sessionMetadata;
|
|
1882
1974
|
interactionHandler;
|
|
1883
1975
|
registry = new PRBEToolRegistry();
|
|
1884
1976
|
grantedPaths = /* @__PURE__ */ new Set();
|
|
1885
1977
|
userCancelled = false;
|
|
1886
|
-
|
|
1978
|
+
activeConnection = null;
|
|
1887
1979
|
pollingTimer = null;
|
|
1888
1980
|
persistedData;
|
|
1889
1981
|
fetchAbortController = null;
|
|
@@ -1938,6 +2030,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1938
2030
|
};
|
|
1939
2031
|
this.interactionHandler = config.interactionHandler;
|
|
1940
2032
|
this.appDataPath = config.appDataPath;
|
|
2033
|
+
this.sessionMetadata = config.sessionMetadata ?? {};
|
|
1941
2034
|
if (this.appDataPath && !this.config.autoApprovedDirs.includes(this.appDataPath)) {
|
|
1942
2035
|
this.config.autoApprovedDirs.push(this.appDataPath);
|
|
1943
2036
|
}
|
|
@@ -2043,6 +2136,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2043
2136
|
get investigationSource() {
|
|
2044
2137
|
return this.currentInvestigationSource;
|
|
2045
2138
|
}
|
|
2139
|
+
sendConversationMessage(content) {
|
|
2140
|
+
this.activeConnection?.sendConversationMessage(content);
|
|
2141
|
+
}
|
|
2046
2142
|
async requestUserInteraction(payload) {
|
|
2047
2143
|
if (!this.interactionHandler) {
|
|
2048
2144
|
throw new PRBEAgentError(
|
|
@@ -2062,6 +2158,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2062
2158
|
} else {
|
|
2063
2159
|
this.state.resolveInteraction(response);
|
|
2064
2160
|
}
|
|
2161
|
+
if (response.type === "request_permission" /* REQUEST_PERMISSION */) {
|
|
2162
|
+
const approved = response.approved;
|
|
2163
|
+
this.sendConversationMessage(approved ? "Approved" : "Denied");
|
|
2164
|
+
} else if (response.type === "request_path_access" /* REQUEST_PATH_ACCESS */) {
|
|
2165
|
+
const granted = response.granted;
|
|
2166
|
+
this.sendConversationMessage(granted ? "Allowed" : "Denied");
|
|
2167
|
+
}
|
|
2065
2168
|
return response;
|
|
2066
2169
|
} catch (err) {
|
|
2067
2170
|
if (this.currentInvestigationSource === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
|
|
@@ -2081,6 +2184,13 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2081
2184
|
}
|
|
2082
2185
|
}
|
|
2083
2186
|
// ---------- Public API ----------
|
|
2187
|
+
/**
|
|
2188
|
+
* Update session metadata. Merged with existing metadata.
|
|
2189
|
+
* Call this to add user profile data, app version, etc. after async initialization.
|
|
2190
|
+
*/
|
|
2191
|
+
updateSessionMetadata(metadata) {
|
|
2192
|
+
this.sessionMetadata = { ...this.sessionMetadata, ...metadata };
|
|
2193
|
+
}
|
|
2084
2194
|
/**
|
|
2085
2195
|
* Register a custom tool that the middleware can invoke during investigations.
|
|
2086
2196
|
*/
|
|
@@ -2114,7 +2224,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2114
2224
|
this.state.appendEvent("Thinking", status.text);
|
|
2115
2225
|
break;
|
|
2116
2226
|
case "completed" /* COMPLETED */:
|
|
2117
|
-
this.state.completeInvestigation(status.report, status.
|
|
2227
|
+
this.state.completeInvestigation(status.report, status.ticketId);
|
|
2118
2228
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2119
2229
|
break;
|
|
2120
2230
|
case "error" /* ERROR */:
|
|
@@ -2144,9 +2254,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2144
2254
|
*/
|
|
2145
2255
|
cancelInvestigation() {
|
|
2146
2256
|
this.userCancelled = true;
|
|
2147
|
-
if (this.
|
|
2148
|
-
this.
|
|
2149
|
-
this.
|
|
2257
|
+
if (this.activeConnection) {
|
|
2258
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2259
|
+
this.activeConnection = null;
|
|
2150
2260
|
}
|
|
2151
2261
|
}
|
|
2152
2262
|
/**
|
|
@@ -2154,9 +2264,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2154
2264
|
*/
|
|
2155
2265
|
cancel() {
|
|
2156
2266
|
this.userCancelled = true;
|
|
2157
|
-
if (this.
|
|
2158
|
-
this.
|
|
2159
|
-
this.
|
|
2267
|
+
if (this.activeConnection) {
|
|
2268
|
+
this.activeConnection.close(1e3, "User cancelled");
|
|
2269
|
+
this.activeConnection = null;
|
|
2160
2270
|
}
|
|
2161
2271
|
this.abortInFlightRequests();
|
|
2162
2272
|
this.stopPolling();
|
|
@@ -2295,7 +2405,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2295
2405
|
this.state.appendCREvent(crID, "Thinking", status.text);
|
|
2296
2406
|
break;
|
|
2297
2407
|
case "completed" /* COMPLETED */:
|
|
2298
|
-
this.state.completeCR(crID, status.report
|
|
2408
|
+
this.state.completeCR(crID, status.report);
|
|
2299
2409
|
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2300
2410
|
break;
|
|
2301
2411
|
case "error" /* ERROR */:
|
|
@@ -2322,31 +2432,44 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2322
2432
|
connectToProxy(query, contextRequestID, emit, isCancelled, ticketId) {
|
|
2323
2433
|
return new Promise((resolve2) => {
|
|
2324
2434
|
const wsUrl = `${MIDDLEWARE_URL}/api/agent/client/ws`;
|
|
2325
|
-
let ws;
|
|
2326
|
-
try {
|
|
2327
|
-
ws = new WebSocket(wsUrl, {
|
|
2328
|
-
headers: {
|
|
2329
|
-
"X-API-Key": this.config.apiKey
|
|
2330
|
-
}
|
|
2331
|
-
});
|
|
2332
|
-
} catch (err) {
|
|
2333
|
-
emit({
|
|
2334
|
-
type: "error" /* ERROR */,
|
|
2335
|
-
message: `Failed to create WebSocket: ${err}`
|
|
2336
|
-
});
|
|
2337
|
-
resolve2(null);
|
|
2338
|
-
return;
|
|
2339
|
-
}
|
|
2340
|
-
this.activeWS = ws;
|
|
2341
2435
|
let uploadBaseUrl;
|
|
2342
2436
|
let resolved = false;
|
|
2343
2437
|
const finish = (result) => {
|
|
2344
2438
|
if (resolved) return;
|
|
2345
2439
|
resolved = true;
|
|
2346
|
-
this.
|
|
2440
|
+
this.activeConnection = null;
|
|
2347
2441
|
resolve2(result);
|
|
2348
2442
|
};
|
|
2349
|
-
|
|
2443
|
+
let conn;
|
|
2444
|
+
try {
|
|
2445
|
+
conn = new InvestigationConnection(
|
|
2446
|
+
wsUrl,
|
|
2447
|
+
this.config.apiKey,
|
|
2448
|
+
(msg) => this.handleMessage(msg, conn, emit, isCancelled, finish, () => uploadBaseUrl, (url) => {
|
|
2449
|
+
uploadBaseUrl = url;
|
|
2450
|
+
}),
|
|
2451
|
+
(message) => {
|
|
2452
|
+
if (!isCancelled()) emit({ type: "error" /* ERROR */, message });
|
|
2453
|
+
finish(null);
|
|
2454
|
+
},
|
|
2455
|
+
() => {
|
|
2456
|
+
if (!resolved) {
|
|
2457
|
+
if (isCancelled()) {
|
|
2458
|
+
finish(null);
|
|
2459
|
+
} else {
|
|
2460
|
+
emit({ type: "error" /* ERROR */, message: "WebSocket connection closed unexpectedly" });
|
|
2461
|
+
finish(null);
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
);
|
|
2466
|
+
} catch (err) {
|
|
2467
|
+
emit({ type: "error" /* ERROR */, message: `Failed to create WebSocket: ${err}` });
|
|
2468
|
+
resolve2(null);
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
this.activeConnection = conn;
|
|
2472
|
+
conn.onopen = () => {
|
|
2350
2473
|
const toolDeclarations = this.registry.allDeclarations().map((decl) => ({
|
|
2351
2474
|
name: decl.name,
|
|
2352
2475
|
description: decl.description,
|
|
@@ -2365,206 +2488,102 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2365
2488
|
os_version: os2.release(),
|
|
2366
2489
|
arch: os2.arch()
|
|
2367
2490
|
};
|
|
2368
|
-
if (contextRequestID)
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
if (
|
|
2372
|
-
startMetadata["
|
|
2491
|
+
if (contextRequestID) startMetadata["context_request_id"] = contextRequestID;
|
|
2492
|
+
if (ticketId) startMetadata["ticket_id"] = ticketId;
|
|
2493
|
+
if (this.appDataPath) startMetadata["app_data_path"] = this.appDataPath;
|
|
2494
|
+
if (Object.keys(this.sessionMetadata).length > 0) {
|
|
2495
|
+
startMetadata["session_metadata"] = this.sessionMetadata;
|
|
2373
2496
|
}
|
|
2374
|
-
if (
|
|
2375
|
-
|
|
2376
|
-
}
|
|
2377
|
-
const startMsg = {
|
|
2378
|
-
type: "start" /* START */,
|
|
2379
|
-
content: query,
|
|
2380
|
-
metadata: startMetadata
|
|
2381
|
-
};
|
|
2382
|
-
try {
|
|
2383
|
-
ws.send(JSON.stringify(startMsg));
|
|
2384
|
-
} catch (err) {
|
|
2385
|
-
emit({
|
|
2386
|
-
type: "error" /* ERROR */,
|
|
2387
|
-
message: `Failed to send start message: ${err}`
|
|
2388
|
-
});
|
|
2497
|
+
if (!conn.send({ type: "start" /* START */, content: query, metadata: startMetadata })) {
|
|
2498
|
+
emit({ type: "error" /* ERROR */, message: "Failed to send start message" });
|
|
2389
2499
|
finish(null);
|
|
2390
2500
|
return;
|
|
2391
2501
|
}
|
|
2392
2502
|
emit({ type: "started" /* STARTED */ });
|
|
2393
2503
|
this.pendingFlaggedFiles = [];
|
|
2394
2504
|
};
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
const
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
label: msg.content ?? `Running ${toolName}`
|
|
2431
|
-
});
|
|
2432
|
-
this.pendingFlaggedFiles = [];
|
|
2433
|
-
const toolResult = redactPII(
|
|
2434
|
-
await this.registry.execute(toolName, args)
|
|
2435
|
-
);
|
|
2436
|
-
emit({
|
|
2437
|
-
type: "observation" /* OBSERVATION */,
|
|
2438
|
-
text: toolResult.substring(0, 200)
|
|
2439
|
-
});
|
|
2440
|
-
let resultMetadata;
|
|
2441
|
-
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2442
|
-
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2443
|
-
const uploadedRefs = [];
|
|
2444
|
-
for (const file of this.pendingFlaggedFiles) {
|
|
2445
|
-
const filename = path5.basename(file.originalPath);
|
|
2446
|
-
const safeName = encodeURIComponent(filename);
|
|
2447
|
-
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2448
|
-
uploadedRefs.push({
|
|
2449
|
-
original_path: file.originalPath,
|
|
2450
|
-
reason: file.reason ?? "",
|
|
2451
|
-
storage_path: storagePath,
|
|
2452
|
-
file_size_bytes: file.data.length
|
|
2453
|
-
});
|
|
2454
|
-
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2455
|
-
const fileData = file.data;
|
|
2456
|
-
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2457
|
-
void _PRBEAgent.backgroundUpload(
|
|
2458
|
-
fileData,
|
|
2459
|
-
uploadUrl,
|
|
2460
|
-
this.config.apiKey,
|
|
2461
|
-
contentType,
|
|
2462
|
-
this.getFetchSignal()
|
|
2463
|
-
);
|
|
2464
|
-
}
|
|
2465
|
-
resultMetadata = { flagged_files: uploadedRefs };
|
|
2466
|
-
this.pendingFlaggedFiles = [];
|
|
2467
|
-
}
|
|
2468
|
-
const resultMsg = {
|
|
2469
|
-
type: "tool_result" /* TOOL_RESULT */,
|
|
2470
|
-
id: callId,
|
|
2471
|
-
name: toolName,
|
|
2472
|
-
content: toolResult,
|
|
2473
|
-
metadata: resultMetadata
|
|
2474
|
-
};
|
|
2475
|
-
try {
|
|
2476
|
-
ws.send(JSON.stringify(resultMsg));
|
|
2477
|
-
} catch {
|
|
2478
|
-
}
|
|
2479
|
-
break;
|
|
2480
|
-
}
|
|
2481
|
-
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2482
|
-
emit({
|
|
2483
|
-
type: "tool_call" /* TOOL_CALL */,
|
|
2484
|
-
name: msg.name ?? "",
|
|
2485
|
-
label: msg.content ?? ""
|
|
2486
|
-
});
|
|
2487
|
-
break;
|
|
2488
|
-
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2489
|
-
emit({
|
|
2490
|
-
type: "observation" /* OBSERVATION */,
|
|
2491
|
-
text: (msg.content ?? "").substring(0, 200)
|
|
2492
|
-
});
|
|
2493
|
-
break;
|
|
2494
|
-
case "complete" /* COMPLETE */: {
|
|
2495
|
-
const report = msg.content ?? "";
|
|
2496
|
-
const userSummary = msg.metadata?.["user_summary"] ?? "";
|
|
2497
|
-
const ticketId2 = msg.metadata?.["ticket_id"];
|
|
2498
|
-
const sessionId = msg.metadata?.["session_id"];
|
|
2499
|
-
emit({
|
|
2500
|
-
type: "completed" /* COMPLETED */,
|
|
2501
|
-
report,
|
|
2502
|
-
userSummary,
|
|
2503
|
-
ticketId: ticketId2
|
|
2504
|
-
});
|
|
2505
|
-
ws.close(1e3, "Complete");
|
|
2506
|
-
finish({ report, userSummary, ticketId: ticketId2, sessionId });
|
|
2507
|
-
break;
|
|
2508
|
-
}
|
|
2509
|
-
case "error" /* ERROR */:
|
|
2510
|
-
emit({
|
|
2511
|
-
type: "error" /* ERROR */,
|
|
2512
|
-
message: msg.content || "Unknown error"
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
async handleMessage(msg, conn, emit, isCancelled, finish, getUploadBaseUrl, setUploadBaseUrl) {
|
|
2508
|
+
if (isCancelled()) {
|
|
2509
|
+
conn.sendCancel();
|
|
2510
|
+
conn.close(1e3, "Cancelled");
|
|
2511
|
+
finish(null);
|
|
2512
|
+
return;
|
|
2513
|
+
}
|
|
2514
|
+
switch (msg.type) {
|
|
2515
|
+
case "thought" /* THOUGHT */:
|
|
2516
|
+
emit({ type: "thought" /* THOUGHT */, text: msg.content ?? "" });
|
|
2517
|
+
break;
|
|
2518
|
+
case "tool_call" /* TOOL_CALL */: {
|
|
2519
|
+
const toolName = msg.name ?? "";
|
|
2520
|
+
const callId = msg.id ?? "";
|
|
2521
|
+
const args = this.extractArgs(msg.metadata);
|
|
2522
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: toolName, label: msg.content ?? `Running ${toolName}` });
|
|
2523
|
+
this.pendingFlaggedFiles = [];
|
|
2524
|
+
const toolResult = redactPII(await this.registry.execute(toolName, args));
|
|
2525
|
+
emit({ type: "observation" /* OBSERVATION */, text: toolResult.substring(0, 200) });
|
|
2526
|
+
let resultMetadata;
|
|
2527
|
+
const uploadBaseUrl = getUploadBaseUrl();
|
|
2528
|
+
if (this.pendingFlaggedFiles.length > 0 && uploadBaseUrl) {
|
|
2529
|
+
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2530
|
+
const uploadedRefs = [];
|
|
2531
|
+
for (const file of this.pendingFlaggedFiles) {
|
|
2532
|
+
const filename = path5.basename(file.originalPath);
|
|
2533
|
+
const safeName = encodeURIComponent(filename);
|
|
2534
|
+
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2535
|
+
uploadedRefs.push({
|
|
2536
|
+
original_path: file.originalPath,
|
|
2537
|
+
reason: file.reason ?? "",
|
|
2538
|
+
storage_path: storagePath,
|
|
2539
|
+
file_size_bytes: file.data.length
|
|
2513
2540
|
});
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
case "session_config" /* SESSION_CONFIG */:
|
|
2518
|
-
uploadBaseUrl = msg.metadata?.["upload_url"];
|
|
2519
|
-
break;
|
|
2520
|
-
case "ping" /* PING */: {
|
|
2521
|
-
const pongMsg = { type: "pong" /* PONG */ };
|
|
2522
|
-
try {
|
|
2523
|
-
ws.send(JSON.stringify(pongMsg));
|
|
2524
|
-
} catch {
|
|
2525
|
-
}
|
|
2526
|
-
break;
|
|
2541
|
+
const uploadUrl = `${uploadBaseUrl}/${safeName}`;
|
|
2542
|
+
const contentType = file.isText ? "text/plain" : "application/octet-stream";
|
|
2543
|
+
void _PRBEAgent.backgroundUpload(file.data, uploadUrl, this.config.apiKey, contentType, this.getFetchSignal());
|
|
2527
2544
|
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
case "tool_result" /* TOOL_RESULT */:
|
|
2531
|
-
case "upload_request" /* UPLOAD_REQUEST */:
|
|
2532
|
-
case "cancel" /* CANCEL */:
|
|
2533
|
-
case "pong" /* PONG */:
|
|
2534
|
-
case "upload_url" /* UPLOAD_URL */:
|
|
2535
|
-
break;
|
|
2545
|
+
resultMetadata = { flagged_files: uploadedRefs };
|
|
2546
|
+
this.pendingFlaggedFiles = [];
|
|
2536
2547
|
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2548
|
+
conn.sendToolResult(callId, toolName, toolResult, resultMetadata);
|
|
2549
|
+
break;
|
|
2550
|
+
}
|
|
2551
|
+
case "server_tool_call" /* SERVER_TOOL_CALL */:
|
|
2552
|
+
emit({ type: "tool_call" /* TOOL_CALL */, name: msg.name ?? "", label: msg.content ?? "" });
|
|
2553
|
+
break;
|
|
2554
|
+
case "server_observation" /* SERVER_OBSERVATION */:
|
|
2555
|
+
emit({ type: "observation" /* OBSERVATION */, text: (msg.content ?? "").substring(0, 200) });
|
|
2556
|
+
break;
|
|
2557
|
+
case "complete" /* COMPLETE */: {
|
|
2558
|
+
const report = msg.content ?? "";
|
|
2559
|
+
const completedTicketId = msg.metadata?.["ticket_id"];
|
|
2560
|
+
const sessionId = msg.metadata?.["session_id"];
|
|
2561
|
+
emit({ type: "completed" /* COMPLETED */, report, ticketId: completedTicketId });
|
|
2562
|
+
conn.close(1e3, "Complete");
|
|
2563
|
+
finish({ report, ticketId: completedTicketId, sessionId });
|
|
2564
|
+
break;
|
|
2565
|
+
}
|
|
2566
|
+
case "error" /* ERROR */:
|
|
2567
|
+
emit({ type: "error" /* ERROR */, message: msg.content || "Unknown error" });
|
|
2568
|
+
conn.close(1e3, "Error received");
|
|
2546
2569
|
finish(null);
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
});
|
|
2557
|
-
finish(null);
|
|
2558
|
-
}
|
|
2570
|
+
break;
|
|
2571
|
+
case "session_config" /* SESSION_CONFIG */:
|
|
2572
|
+
setUploadBaseUrl(msg.metadata?.["upload_url"]);
|
|
2573
|
+
break;
|
|
2574
|
+
case "conversation_update" /* CONVERSATION_UPDATE */: {
|
|
2575
|
+
try {
|
|
2576
|
+
const entry = JSON.parse(msg.content ?? "{}");
|
|
2577
|
+
this.state.appendConversation(entry);
|
|
2578
|
+
} catch {
|
|
2559
2579
|
}
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
} catch {
|
|
2580
|
+
break;
|
|
2581
|
+
}
|
|
2582
|
+
case "ping" /* PING */:
|
|
2583
|
+
conn.sendPong();
|
|
2584
|
+
break;
|
|
2585
|
+
default:
|
|
2586
|
+
break;
|
|
2568
2587
|
}
|
|
2569
2588
|
}
|
|
2570
2589
|
extractArgs(metadata) {
|
|
@@ -2682,6 +2701,7 @@ var DEFAULT_PRBE_STATE = {
|
|
|
2682
2701
|
summary: "",
|
|
2683
2702
|
currentQuery: "",
|
|
2684
2703
|
resolvedInteractions: [],
|
|
2704
|
+
conversationHistory: [],
|
|
2685
2705
|
completedInvestigations: [],
|
|
2686
2706
|
activeCRs: [],
|
|
2687
2707
|
completedCRs: [],
|
|
@@ -2719,6 +2739,7 @@ function serializePRBEState(state) {
|
|
|
2719
2739
|
pendingInteraction: state.pendingInteraction,
|
|
2720
2740
|
resolvedInteractions: state.resolvedInteractions,
|
|
2721
2741
|
agentMessage: state.agentMessage,
|
|
2742
|
+
conversationHistory: state.conversationHistory,
|
|
2722
2743
|
completedInvestigations: state.completedInvestigations.map((inv) => ({
|
|
2723
2744
|
id: inv.id,
|
|
2724
2745
|
query: inv.query,
|
|
@@ -2727,6 +2748,7 @@ function serializePRBEState(state) {
|
|
|
2727
2748
|
ticketId: inv.ticketId,
|
|
2728
2749
|
events: inv.events,
|
|
2729
2750
|
resolvedInteractions: inv.resolvedInteractions,
|
|
2751
|
+
conversationHistory: inv.conversationHistory,
|
|
2730
2752
|
completedAt: inv.completedAt.toISOString()
|
|
2731
2753
|
})),
|
|
2732
2754
|
activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
|
|
@@ -2749,6 +2771,7 @@ var PROBE_MARK_SVG = `<svg width="256" height="256" viewBox="0 0 256 256" fill="
|
|
|
2749
2771
|
AskUserTool,
|
|
2750
2772
|
BashExecuteTool,
|
|
2751
2773
|
ClearAppLogsTool,
|
|
2774
|
+
ConversationRole,
|
|
2752
2775
|
DEFAULT_PRBE_STATE,
|
|
2753
2776
|
FindFilesTool,
|
|
2754
2777
|
FlagAppLogsTool,
|