@prbe.ai/electron-sdk 0.1.16 → 0.1.18
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 +25 -17
- package/dist/index.d.ts +25 -17
- package/dist/index.js +311 -466
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +310 -466
- package/dist/index.mjs.map +1 -1
- package/dist/{types-Cyfgy1uD.d.mts → types-BeZ2nQ9x.d.mts} +66 -46
- package/dist/{types-Cyfgy1uD.d.ts → types-BeZ2nQ9x.d.ts} +66 -46
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +5 -5
- package/dist/types.js.map +1 -1
- package/dist/types.mjs +5 -5
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.1.
|
|
2
|
+
var version = "0.1.18";
|
|
3
3
|
|
|
4
4
|
// src/agent.ts
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
5
|
+
import * as fs2 from "fs";
|
|
6
|
+
import * as path4 from "path";
|
|
7
|
+
import * as os from "os";
|
|
8
8
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
9
9
|
|
|
10
10
|
// src/models.ts
|
|
@@ -53,6 +53,11 @@ var ToolName = /* @__PURE__ */ ((ToolName2) => {
|
|
|
53
53
|
ToolName2["CLIENT_MESSAGE_USER"] = "client_message_user";
|
|
54
54
|
return ToolName2;
|
|
55
55
|
})(ToolName || {});
|
|
56
|
+
var UserIdentifierType = /* @__PURE__ */ ((UserIdentifierType2) => {
|
|
57
|
+
UserIdentifierType2["EMAIL"] = "email";
|
|
58
|
+
UserIdentifierType2["ID"] = "id";
|
|
59
|
+
return UserIdentifierType2;
|
|
60
|
+
})(UserIdentifierType || {});
|
|
56
61
|
var PRBEAgentConfigKey = /* @__PURE__ */ ((PRBEAgentConfigKey3) => {
|
|
57
62
|
PRBEAgentConfigKey3["API_KEY"] = "apiKey";
|
|
58
63
|
PRBEAgentConfigKey3["AUTO_APPROVED_DIRS"] = "autoApprovedDirs";
|
|
@@ -187,8 +192,8 @@ var PRBEStateEvent = /* @__PURE__ */ ((PRBEStateEvent2) => {
|
|
|
187
192
|
PRBEStateEvent2["EVENT"] = "event";
|
|
188
193
|
PRBEStateEvent2["COMPLETE"] = "complete";
|
|
189
194
|
PRBEStateEvent2["ERROR"] = "error";
|
|
190
|
-
PRBEStateEvent2["
|
|
191
|
-
PRBEStateEvent2["
|
|
195
|
+
PRBEStateEvent2["BACKGROUND_START"] = "background-start";
|
|
196
|
+
PRBEStateEvent2["BACKGROUND_COMPLETE"] = "background-complete";
|
|
192
197
|
PRBEStateEvent2["TICKETS_CHANGED"] = "tickets-changed";
|
|
193
198
|
PRBEStateEvent2["TICKET_INFO"] = "ticket-info";
|
|
194
199
|
PRBEStateEvent2["INTERACTION_REQUESTED"] = "interaction-requested";
|
|
@@ -210,18 +215,20 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
210
215
|
conversationHistory = [];
|
|
211
216
|
// Completed user investigations (history)
|
|
212
217
|
completedInvestigations = [];
|
|
213
|
-
// Background context requests
|
|
214
|
-
|
|
215
|
-
|
|
218
|
+
// Background investigations (context requests, external requests, etc.)
|
|
219
|
+
activeBackgroundInvestigations = /* @__PURE__ */ new Map();
|
|
220
|
+
completedBackgroundInvestigations = [];
|
|
216
221
|
// Tracked tickets
|
|
217
222
|
trackedSessionIDs = [];
|
|
218
223
|
ticketInfo = [];
|
|
224
|
+
// Agent history
|
|
225
|
+
agentHistory = [];
|
|
219
226
|
// Computed
|
|
220
227
|
get hasActiveWork() {
|
|
221
|
-
return this.isInvestigating || this.
|
|
228
|
+
return this.isInvestigating || this.activeBackgroundInvestigations.size > 0;
|
|
222
229
|
}
|
|
223
|
-
get
|
|
224
|
-
return this.
|
|
230
|
+
get activeBackgroundCount() {
|
|
231
|
+
return this.activeBackgroundInvestigations.size;
|
|
225
232
|
}
|
|
226
233
|
get isActive() {
|
|
227
234
|
return this.isInvestigating || this.report.length > 0 || this.investigationError != null;
|
|
@@ -243,6 +250,12 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
243
250
|
this.conversationHistory.push(entry);
|
|
244
251
|
this.emit("status" /* STATUS */);
|
|
245
252
|
}
|
|
253
|
+
appendBackgroundConversation(backgroundId, entry) {
|
|
254
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
255
|
+
if (!bg) return;
|
|
256
|
+
bg.conversationHistory.push(entry);
|
|
257
|
+
this.emit("status" /* STATUS */);
|
|
258
|
+
}
|
|
246
259
|
resetInvestigation() {
|
|
247
260
|
this.isInvestigating = false;
|
|
248
261
|
this.events = [];
|
|
@@ -318,17 +331,17 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
318
331
|
this.emit("interaction-resolved" /* INTERACTION_RESOLVED */);
|
|
319
332
|
this.emit("status" /* STATUS */);
|
|
320
333
|
}
|
|
321
|
-
|
|
322
|
-
const
|
|
323
|
-
if (!
|
|
324
|
-
|
|
334
|
+
setBackgroundPendingInteraction(backgroundId, payload) {
|
|
335
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
336
|
+
if (!bg) return;
|
|
337
|
+
bg.pendingInteraction = payload;
|
|
325
338
|
this.emit("interaction-requested" /* INTERACTION_REQUESTED */, payload);
|
|
326
339
|
this.emit("status" /* STATUS */);
|
|
327
340
|
}
|
|
328
|
-
|
|
329
|
-
const
|
|
330
|
-
if (!
|
|
331
|
-
|
|
341
|
+
clearBackgroundPendingInteraction(backgroundId) {
|
|
342
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
343
|
+
if (!bg) return;
|
|
344
|
+
bg.pendingInteraction = void 0;
|
|
332
345
|
this.emit("interaction-resolved" /* INTERACTION_RESOLVED */);
|
|
333
346
|
this.emit("status" /* STATUS */);
|
|
334
347
|
}
|
|
@@ -344,18 +357,18 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
344
357
|
this.emit("interaction-resolved" /* INTERACTION_RESOLVED */);
|
|
345
358
|
this.emit("status" /* STATUS */);
|
|
346
359
|
}
|
|
347
|
-
|
|
348
|
-
const
|
|
349
|
-
if (!
|
|
350
|
-
const resolved =
|
|
360
|
+
resolveBackgroundInteraction(backgroundId, response) {
|
|
361
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
362
|
+
if (!bg || !bg.pendingInteraction) return;
|
|
363
|
+
const resolved = bg.resolvedInteractions ?? [];
|
|
351
364
|
resolved.push({
|
|
352
|
-
interactionId:
|
|
353
|
-
payload:
|
|
365
|
+
interactionId: bg.pendingInteraction.interactionId,
|
|
366
|
+
payload: bg.pendingInteraction,
|
|
354
367
|
response,
|
|
355
|
-
eventIndex:
|
|
368
|
+
eventIndex: bg.events.length
|
|
356
369
|
});
|
|
357
|
-
|
|
358
|
-
|
|
370
|
+
bg.resolvedInteractions = resolved;
|
|
371
|
+
bg.pendingInteraction = void 0;
|
|
359
372
|
this.emit("interaction-resolved" /* INTERACTION_RESOLVED */);
|
|
360
373
|
this.emit("status" /* STATUS */);
|
|
361
374
|
}
|
|
@@ -364,10 +377,10 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
364
377
|
this.emit("agent-message" /* AGENT_MESSAGE */, { message });
|
|
365
378
|
this.emit("status" /* STATUS */);
|
|
366
379
|
}
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
if (!
|
|
370
|
-
|
|
380
|
+
setBackgroundAgentMessage(backgroundId, message) {
|
|
381
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
382
|
+
if (!bg) return;
|
|
383
|
+
bg.agentMessage = message;
|
|
371
384
|
this.emit("agent-message" /* AGENT_MESSAGE */, { message });
|
|
372
385
|
this.emit("status" /* STATUS */);
|
|
373
386
|
}
|
|
@@ -378,14 +391,17 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
378
391
|
this.emit("status" /* STATUS */);
|
|
379
392
|
}
|
|
380
393
|
}
|
|
381
|
-
// ----------
|
|
382
|
-
|
|
383
|
-
const
|
|
394
|
+
// ---------- Background investigation state mutations ----------
|
|
395
|
+
beginBackgroundInvestigation(id, query, slug, ticketId, source, sourceDetail) {
|
|
396
|
+
const bg = {
|
|
384
397
|
id,
|
|
385
398
|
query,
|
|
386
399
|
slug,
|
|
387
400
|
ticketId,
|
|
401
|
+
source,
|
|
402
|
+
sourceDetail,
|
|
388
403
|
events: [],
|
|
404
|
+
conversationHistory: [],
|
|
389
405
|
resolvedInteractions: [],
|
|
390
406
|
isRunning: true,
|
|
391
407
|
isCompleted: false,
|
|
@@ -394,20 +410,20 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
394
410
|
summary: "",
|
|
395
411
|
startedAt: /* @__PURE__ */ new Date()
|
|
396
412
|
};
|
|
397
|
-
this.
|
|
398
|
-
this.emit("
|
|
413
|
+
this.activeBackgroundInvestigations.set(id, bg);
|
|
414
|
+
this.emit("background-start" /* BACKGROUND_START */, bg);
|
|
399
415
|
this.emit("status" /* STATUS */);
|
|
400
416
|
}
|
|
401
|
-
|
|
402
|
-
const
|
|
403
|
-
if (!
|
|
404
|
-
if (
|
|
405
|
-
const last =
|
|
417
|
+
appendBackgroundEvent(backgroundId, label, detail, completed = false) {
|
|
418
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
419
|
+
if (!bg) return;
|
|
420
|
+
if (bg.events.length > 0) {
|
|
421
|
+
const last = bg.events[bg.events.length - 1];
|
|
406
422
|
if (!last.isCompleted && !completed) {
|
|
407
423
|
last.isCompleted = true;
|
|
408
424
|
}
|
|
409
425
|
}
|
|
410
|
-
|
|
426
|
+
bg.events.push({
|
|
411
427
|
id: randomUUID(),
|
|
412
428
|
label,
|
|
413
429
|
detail,
|
|
@@ -416,47 +432,47 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
416
432
|
});
|
|
417
433
|
this.emit("status" /* STATUS */);
|
|
418
434
|
}
|
|
419
|
-
|
|
420
|
-
const
|
|
421
|
-
if (!
|
|
422
|
-
|
|
435
|
+
attachBackgroundObservation(backgroundId, text) {
|
|
436
|
+
const bg = this.activeBackgroundInvestigations.get(backgroundId);
|
|
437
|
+
if (!bg || bg.events.length === 0) return;
|
|
438
|
+
bg.events[bg.events.length - 1].detail = text;
|
|
423
439
|
this.emit("status" /* STATUS */);
|
|
424
440
|
}
|
|
425
|
-
|
|
426
|
-
const
|
|
427
|
-
if (!
|
|
428
|
-
this.
|
|
429
|
-
if (
|
|
430
|
-
|
|
441
|
+
completeBackgroundInvestigation(id, report) {
|
|
442
|
+
const bg = this.activeBackgroundInvestigations.get(id);
|
|
443
|
+
if (!bg) return;
|
|
444
|
+
this.activeBackgroundInvestigations.delete(id);
|
|
445
|
+
if (bg.events.length > 0) {
|
|
446
|
+
bg.events[bg.events.length - 1].isCompleted = true;
|
|
431
447
|
}
|
|
432
|
-
|
|
448
|
+
bg.events.push({
|
|
433
449
|
id: randomUUID(),
|
|
434
450
|
label: "Done",
|
|
435
451
|
isCompleted: true,
|
|
436
452
|
isExpanded: false
|
|
437
453
|
});
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
this.
|
|
442
|
-
this.emit("
|
|
454
|
+
bg.isRunning = false;
|
|
455
|
+
bg.isCompleted = true;
|
|
456
|
+
bg.report = report;
|
|
457
|
+
this.completedBackgroundInvestigations.unshift(bg);
|
|
458
|
+
this.emit("background-complete" /* BACKGROUND_COMPLETE */, bg);
|
|
443
459
|
this.emit("status" /* STATUS */);
|
|
444
460
|
}
|
|
445
|
-
|
|
446
|
-
const
|
|
447
|
-
if (!
|
|
448
|
-
this.
|
|
449
|
-
|
|
461
|
+
failBackgroundInvestigation(id, message) {
|
|
462
|
+
const bg = this.activeBackgroundInvestigations.get(id);
|
|
463
|
+
if (!bg) return;
|
|
464
|
+
this.activeBackgroundInvestigations.delete(id);
|
|
465
|
+
bg.events.push({
|
|
450
466
|
id: randomUUID(),
|
|
451
467
|
label: `Error: ${message}`,
|
|
452
468
|
isCompleted: false,
|
|
453
469
|
isExpanded: false
|
|
454
470
|
});
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
this.
|
|
459
|
-
this.emit("
|
|
471
|
+
bg.isRunning = false;
|
|
472
|
+
bg.isFailed = true;
|
|
473
|
+
bg.errorMessage = message;
|
|
474
|
+
this.completedBackgroundInvestigations.unshift(bg);
|
|
475
|
+
this.emit("background-complete" /* BACKGROUND_COMPLETE */, bg);
|
|
460
476
|
this.emit("status" /* STATUS */);
|
|
461
477
|
}
|
|
462
478
|
// ---------- Tickets ----------
|
|
@@ -470,6 +486,10 @@ var PRBEAgentState = class extends EventEmitter {
|
|
|
470
486
|
this.emit("ticket-info" /* TICKET_INFO */, info);
|
|
471
487
|
this.emit("status" /* STATUS */);
|
|
472
488
|
}
|
|
489
|
+
updateAgentHistory(tickets) {
|
|
490
|
+
this.agentHistory = tickets;
|
|
491
|
+
this.emit("status" /* STATUS */);
|
|
492
|
+
}
|
|
473
493
|
};
|
|
474
494
|
|
|
475
495
|
// src/tools/index.ts
|
|
@@ -485,6 +505,7 @@ var InteractionType = /* @__PURE__ */ ((InteractionType2) => {
|
|
|
485
505
|
var InvestigationSource = /* @__PURE__ */ ((InvestigationSource2) => {
|
|
486
506
|
InvestigationSource2["USER"] = "user";
|
|
487
507
|
InvestigationSource2["CONTEXT_REQUEST"] = "context_request";
|
|
508
|
+
InvestigationSource2["EXTERNAL_REQUEST"] = "external_request";
|
|
488
509
|
return InvestigationSource2;
|
|
489
510
|
})(InvestigationSource || {});
|
|
490
511
|
|
|
@@ -1692,197 +1713,20 @@ var BashExecuteTool = class {
|
|
|
1692
1713
|
}
|
|
1693
1714
|
};
|
|
1694
1715
|
|
|
1695
|
-
// src/
|
|
1696
|
-
|
|
1697
|
-
import * as path4 from "path";
|
|
1698
|
-
import * as os from "os";
|
|
1699
|
-
import * as crypto from "crypto";
|
|
1700
|
-
var HKDF_SALT = Buffer.from("prbe-history-encryption-salt", "utf-8");
|
|
1701
|
-
var HKDF_INFO = Buffer.from("prbe-history-v1", "utf-8");
|
|
1702
|
-
function getAppDataDir() {
|
|
1716
|
+
// src/agent.ts
|
|
1717
|
+
function getPersistencePath() {
|
|
1703
1718
|
const appData = process.env["APPDATA"] || (process.platform === "darwin" ? path4.join(os.homedir(), "Library", "Application Support") : path4.join(os.homedir(), ".local", "share"));
|
|
1704
|
-
|
|
1705
|
-
}
|
|
1706
|
-
function getHistoryDir() {
|
|
1707
|
-
const dir = path4.join(getAppDataDir(), "history" /* HISTORY_DIR */);
|
|
1719
|
+
const dir = path4.join(appData, "prbe-agent");
|
|
1708
1720
|
if (!fs2.existsSync(dir)) {
|
|
1709
1721
|
fs2.mkdirSync(dir, { recursive: true });
|
|
1710
1722
|
}
|
|
1711
|
-
return dir;
|
|
1712
|
-
}
|
|
1713
|
-
function deriveKey(apiKey) {
|
|
1714
|
-
return Buffer.from(
|
|
1715
|
-
crypto.hkdfSync(
|
|
1716
|
-
"sha256",
|
|
1717
|
-
Buffer.from(apiKey, "utf-8"),
|
|
1718
|
-
HKDF_SALT,
|
|
1719
|
-
HKDF_INFO,
|
|
1720
|
-
32 /* KEY_LENGTH */
|
|
1721
|
-
)
|
|
1722
|
-
);
|
|
1723
|
-
}
|
|
1724
|
-
function encrypt(plaintext, key) {
|
|
1725
|
-
const iv = crypto.randomBytes(12 /* IV_LENGTH */);
|
|
1726
|
-
const cipher = crypto.createCipheriv(
|
|
1727
|
-
"aes-256-gcm" /* ALGORITHM */,
|
|
1728
|
-
key,
|
|
1729
|
-
iv,
|
|
1730
|
-
{ authTagLength: 16 /* AUTH_TAG_LENGTH */ }
|
|
1731
|
-
);
|
|
1732
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
1733
|
-
const authTag = cipher.getAuthTag();
|
|
1734
|
-
return Buffer.concat([iv, authTag, encrypted]);
|
|
1735
|
-
}
|
|
1736
|
-
function decrypt(data, key) {
|
|
1737
|
-
const iv = data.subarray(0, 12 /* IV_LENGTH */);
|
|
1738
|
-
const authTag = data.subarray(
|
|
1739
|
-
12 /* IV_LENGTH */,
|
|
1740
|
-
12 /* IV_LENGTH */ + 16 /* AUTH_TAG_LENGTH */
|
|
1741
|
-
);
|
|
1742
|
-
const ciphertext = data.subarray(
|
|
1743
|
-
12 /* IV_LENGTH */ + 16 /* AUTH_TAG_LENGTH */
|
|
1744
|
-
);
|
|
1745
|
-
const decipher = crypto.createDecipheriv(
|
|
1746
|
-
"aes-256-gcm" /* ALGORITHM */,
|
|
1747
|
-
key,
|
|
1748
|
-
iv,
|
|
1749
|
-
{ authTagLength: 16 /* AUTH_TAG_LENGTH */ }
|
|
1750
|
-
);
|
|
1751
|
-
decipher.setAuthTag(authTag);
|
|
1752
|
-
return decipher.update(ciphertext) + decipher.final("utf-8");
|
|
1753
|
-
}
|
|
1754
|
-
var HistoryStore = class {
|
|
1755
|
-
key;
|
|
1756
|
-
constructor(apiKey) {
|
|
1757
|
-
this.key = deriveKey(apiKey);
|
|
1758
|
-
}
|
|
1759
|
-
load() {
|
|
1760
|
-
const investigations = [];
|
|
1761
|
-
const crs = [];
|
|
1762
|
-
try {
|
|
1763
|
-
const dir = getHistoryDir();
|
|
1764
|
-
let files;
|
|
1765
|
-
try {
|
|
1766
|
-
files = fs2.readdirSync(dir);
|
|
1767
|
-
} catch {
|
|
1768
|
-
return { investigations, crs };
|
|
1769
|
-
}
|
|
1770
|
-
for (const filename of files) {
|
|
1771
|
-
try {
|
|
1772
|
-
const filePath = path4.join(dir, filename);
|
|
1773
|
-
const raw = fs2.readFileSync(filePath);
|
|
1774
|
-
const json = decrypt(raw, this.key);
|
|
1775
|
-
if (filename.startsWith("inv-") && filename.endsWith(".json")) {
|
|
1776
|
-
const item = JSON.parse(json);
|
|
1777
|
-
investigations.push({
|
|
1778
|
-
...item,
|
|
1779
|
-
completedAt: new Date(item.completedAt)
|
|
1780
|
-
});
|
|
1781
|
-
} else if (filename.startsWith("cr-") && filename.endsWith(".json")) {
|
|
1782
|
-
const item = JSON.parse(json);
|
|
1783
|
-
crs.push({
|
|
1784
|
-
...item,
|
|
1785
|
-
startedAt: new Date(item.startedAt),
|
|
1786
|
-
resolvedInteractions: item.resolvedInteractions ?? []
|
|
1787
|
-
});
|
|
1788
|
-
}
|
|
1789
|
-
} catch {
|
|
1790
|
-
console.warn(`[PRBEAgent] Skipping unreadable history file: ${filename}`);
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
} catch {
|
|
1794
|
-
}
|
|
1795
|
-
investigations.sort(
|
|
1796
|
-
(a, b) => b.completedAt.getTime() - a.completedAt.getTime()
|
|
1797
|
-
);
|
|
1798
|
-
crs.sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime());
|
|
1799
|
-
return { investigations, crs };
|
|
1800
|
-
}
|
|
1801
|
-
save(investigations, crs) {
|
|
1802
|
-
try {
|
|
1803
|
-
const dir = getHistoryDir();
|
|
1804
|
-
const desiredFiles = /* @__PURE__ */ new Set();
|
|
1805
|
-
for (const inv of investigations) {
|
|
1806
|
-
const filename = `inv-${inv.id}.json`;
|
|
1807
|
-
desiredFiles.add(filename);
|
|
1808
|
-
const data = {
|
|
1809
|
-
id: inv.id,
|
|
1810
|
-
query: inv.query,
|
|
1811
|
-
report: inv.report,
|
|
1812
|
-
summary: inv.summary,
|
|
1813
|
-
ticketId: inv.ticketId,
|
|
1814
|
-
events: inv.events,
|
|
1815
|
-
resolvedInteractions: inv.resolvedInteractions,
|
|
1816
|
-
conversationHistory: inv.conversationHistory,
|
|
1817
|
-
completedAt: inv.completedAt.toISOString()
|
|
1818
|
-
};
|
|
1819
|
-
fs2.writeFileSync(
|
|
1820
|
-
path4.join(dir, filename),
|
|
1821
|
-
encrypt(JSON.stringify(data), this.key)
|
|
1822
|
-
);
|
|
1823
|
-
}
|
|
1824
|
-
for (const cr of crs) {
|
|
1825
|
-
const filename = `cr-${cr.id}.json`;
|
|
1826
|
-
desiredFiles.add(filename);
|
|
1827
|
-
const data = {
|
|
1828
|
-
id: cr.id,
|
|
1829
|
-
query: cr.query,
|
|
1830
|
-
slug: cr.slug,
|
|
1831
|
-
ticketId: cr.ticketId,
|
|
1832
|
-
events: cr.events,
|
|
1833
|
-
isRunning: cr.isRunning,
|
|
1834
|
-
isCompleted: cr.isCompleted,
|
|
1835
|
-
isFailed: cr.isFailed,
|
|
1836
|
-
report: cr.report,
|
|
1837
|
-
summary: cr.summary,
|
|
1838
|
-
errorMessage: cr.errorMessage,
|
|
1839
|
-
startedAt: cr.startedAt.toISOString(),
|
|
1840
|
-
pendingInteraction: cr.pendingInteraction,
|
|
1841
|
-
resolvedInteractions: cr.resolvedInteractions ?? []
|
|
1842
|
-
};
|
|
1843
|
-
fs2.writeFileSync(
|
|
1844
|
-
path4.join(dir, filename),
|
|
1845
|
-
encrypt(JSON.stringify(data), this.key)
|
|
1846
|
-
);
|
|
1847
|
-
}
|
|
1848
|
-
try {
|
|
1849
|
-
const existing = fs2.readdirSync(dir);
|
|
1850
|
-
for (const filename of existing) {
|
|
1851
|
-
if (!desiredFiles.has(filename)) {
|
|
1852
|
-
fs2.unlinkSync(path4.join(dir, filename));
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
|
-
} catch {
|
|
1856
|
-
}
|
|
1857
|
-
} catch {
|
|
1858
|
-
console.error("[PRBEAgent] Failed to save investigation history");
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
|
-
static clear() {
|
|
1862
|
-
try {
|
|
1863
|
-
const dir = path4.join(getAppDataDir(), "history" /* HISTORY_DIR */);
|
|
1864
|
-
if (fs2.existsSync(dir)) {
|
|
1865
|
-
fs2.rmSync(dir, { recursive: true, force: true });
|
|
1866
|
-
}
|
|
1867
|
-
} catch {
|
|
1868
|
-
}
|
|
1869
|
-
}
|
|
1870
|
-
};
|
|
1871
|
-
|
|
1872
|
-
// src/agent.ts
|
|
1873
|
-
function getPersistencePath() {
|
|
1874
|
-
const appData = process.env["APPDATA"] || (process.platform === "darwin" ? path5.join(os2.homedir(), "Library", "Application Support") : path5.join(os2.homedir(), ".local", "share"));
|
|
1875
|
-
const dir = path5.join(appData, "prbe-agent");
|
|
1876
|
-
if (!fs3.existsSync(dir)) {
|
|
1877
|
-
fs3.mkdirSync(dir, { recursive: true });
|
|
1878
|
-
}
|
|
1879
|
-
return path5.join(dir, "agent-state.json");
|
|
1723
|
+
return path4.join(dir, "agent-state.json");
|
|
1880
1724
|
}
|
|
1881
1725
|
function loadPersistedData() {
|
|
1882
1726
|
try {
|
|
1883
1727
|
const filePath = getPersistencePath();
|
|
1884
|
-
if (
|
|
1885
|
-
const raw =
|
|
1728
|
+
if (fs2.existsSync(filePath)) {
|
|
1729
|
+
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
1886
1730
|
return JSON.parse(raw);
|
|
1887
1731
|
}
|
|
1888
1732
|
} catch {
|
|
@@ -1892,7 +1736,7 @@ function loadPersistedData() {
|
|
|
1892
1736
|
function savePersistedData(data) {
|
|
1893
1737
|
try {
|
|
1894
1738
|
const filePath = getPersistencePath();
|
|
1895
|
-
|
|
1739
|
+
fs2.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
1896
1740
|
} catch {
|
|
1897
1741
|
console.error("[PRBEAgent] Failed to save persisted data");
|
|
1898
1742
|
}
|
|
@@ -1912,10 +1756,12 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1912
1756
|
persistedData;
|
|
1913
1757
|
fetchAbortController = null;
|
|
1914
1758
|
currentInvestigationSource = "user" /* USER */;
|
|
1915
|
-
|
|
1916
|
-
historyStore;
|
|
1759
|
+
currentBackgroundId = null;
|
|
1917
1760
|
/** Files flagged during the current tool call — uploaded immediately after the tool returns. */
|
|
1918
1761
|
pendingFlaggedFiles = [];
|
|
1762
|
+
// ---------- User Identifier ----------
|
|
1763
|
+
userEmail;
|
|
1764
|
+
userId;
|
|
1919
1765
|
// ---------- Persistence ----------
|
|
1920
1766
|
get agentID() {
|
|
1921
1767
|
if (this.persistedData.agentId) {
|
|
@@ -1926,30 +1772,6 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1926
1772
|
savePersistedData(this.persistedData);
|
|
1927
1773
|
return newID;
|
|
1928
1774
|
}
|
|
1929
|
-
get trackedSessionIDs() {
|
|
1930
|
-
return this.persistedData.sessionIds ?? [];
|
|
1931
|
-
}
|
|
1932
|
-
set trackedSessionIDs(ids) {
|
|
1933
|
-
this.persistedData.sessionIds = ids;
|
|
1934
|
-
savePersistedData(this.persistedData);
|
|
1935
|
-
this.state.updateTrackedSessionIDs(ids);
|
|
1936
|
-
this.syncPolling(ids.length > 0);
|
|
1937
|
-
}
|
|
1938
|
-
syncPolling(hasSessions) {
|
|
1939
|
-
if (this.config.backgroundPolling && hasSessions) {
|
|
1940
|
-
if (this.pollingTimer === null) {
|
|
1941
|
-
this.startPolling();
|
|
1942
|
-
}
|
|
1943
|
-
} else if (!hasSessions) {
|
|
1944
|
-
this.stopPolling();
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
addTrackedSession(id) {
|
|
1948
|
-
const ids = this.trackedSessionIDs;
|
|
1949
|
-
if (!ids.includes(id)) {
|
|
1950
|
-
this.trackedSessionIDs = [...ids, id];
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
1775
|
// ---------- Constructor ----------
|
|
1954
1776
|
constructor(config) {
|
|
1955
1777
|
this.config = {
|
|
@@ -1969,10 +1791,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
1969
1791
|
this.state = new PRBEAgentState();
|
|
1970
1792
|
this.logCapture = new PRBELogCapture(this.config.maxLogEntries);
|
|
1971
1793
|
this.persistedData = loadPersistedData();
|
|
1972
|
-
|
|
1973
|
-
const history = this.historyStore.load();
|
|
1974
|
-
this.state.completedInvestigations = history.investigations;
|
|
1975
|
-
this.state.completedCRs = history.crs;
|
|
1794
|
+
void this.agentID;
|
|
1976
1795
|
const roots = this.config.autoApprovedDirs;
|
|
1977
1796
|
const requester = this.interactionHandler ? this : void 0;
|
|
1978
1797
|
const grantedPaths = this.grantedPaths;
|
|
@@ -2004,8 +1823,8 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2004
1823
|
[{ name: "message", type: "STRING" /* STRING */, description: "Message for the user", required: true }],
|
|
2005
1824
|
async (args) => {
|
|
2006
1825
|
const message = args["message"] ?? "";
|
|
2007
|
-
if (this.currentInvestigationSource
|
|
2008
|
-
this.state.
|
|
1826
|
+
if (this.currentInvestigationSource !== "user" /* USER */ && this.currentBackgroundId) {
|
|
1827
|
+
this.state.setBackgroundAgentMessage(this.currentBackgroundId, message);
|
|
2009
1828
|
} else {
|
|
2010
1829
|
this.state.setAgentMessage(message);
|
|
2011
1830
|
}
|
|
@@ -2022,9 +1841,8 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2022
1841
|
if (config.ipcMain) {
|
|
2023
1842
|
this.hookRendererLogs(config.ipcMain, config.rendererLogChannel ?? "prbe-renderer-log");
|
|
2024
1843
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
this.trackedSessionIDs = existingSessions;
|
|
1844
|
+
if (this.config.backgroundPolling) {
|
|
1845
|
+
this.startPolling();
|
|
2028
1846
|
}
|
|
2029
1847
|
}
|
|
2030
1848
|
// ---------- Log integration ----------
|
|
@@ -2078,15 +1896,15 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2078
1896
|
"No interaction handler configured"
|
|
2079
1897
|
);
|
|
2080
1898
|
}
|
|
2081
|
-
if (this.currentInvestigationSource
|
|
2082
|
-
this.state.
|
|
1899
|
+
if (this.currentInvestigationSource !== "user" /* USER */ && this.currentBackgroundId) {
|
|
1900
|
+
this.state.setBackgroundPendingInteraction(this.currentBackgroundId, payload);
|
|
2083
1901
|
} else {
|
|
2084
1902
|
this.state.setPendingInteraction(payload);
|
|
2085
1903
|
}
|
|
2086
1904
|
try {
|
|
2087
1905
|
const response = await this.interactionHandler.handleInteraction(payload);
|
|
2088
|
-
if (this.currentInvestigationSource
|
|
2089
|
-
this.state.
|
|
1906
|
+
if (this.currentInvestigationSource !== "user" /* USER */ && this.currentBackgroundId) {
|
|
1907
|
+
this.state.resolveBackgroundInteraction(this.currentBackgroundId, response);
|
|
2090
1908
|
} else {
|
|
2091
1909
|
this.state.resolveInteraction(response);
|
|
2092
1910
|
}
|
|
@@ -2099,8 +1917,8 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2099
1917
|
}
|
|
2100
1918
|
return response;
|
|
2101
1919
|
} catch (err) {
|
|
2102
|
-
if (this.currentInvestigationSource
|
|
2103
|
-
this.state.
|
|
1920
|
+
if (this.currentInvestigationSource !== "user" /* USER */ && this.currentBackgroundId) {
|
|
1921
|
+
this.state.clearBackgroundPendingInteraction(this.currentBackgroundId);
|
|
2104
1922
|
} else {
|
|
2105
1923
|
this.state.clearPendingInteraction();
|
|
2106
1924
|
}
|
|
@@ -2123,6 +1941,47 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2123
1941
|
updateSessionMetadata(metadata) {
|
|
2124
1942
|
this.sessionMetadata = { ...this.sessionMetadata, ...metadata };
|
|
2125
1943
|
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Set a user identifier for this agent. Persists to the backend agents table.
|
|
1946
|
+
* Can be called multiple times with different types to set both email and ID.
|
|
1947
|
+
* Also auto-injects user_email and/or user_id into session metadata for investigations.
|
|
1948
|
+
*/
|
|
1949
|
+
setUserIdentifier(type, value) {
|
|
1950
|
+
if (type === "email" /* EMAIL */) {
|
|
1951
|
+
this.userEmail = value;
|
|
1952
|
+
} else {
|
|
1953
|
+
this.userId = value;
|
|
1954
|
+
}
|
|
1955
|
+
this.syncUserIdentifierToBackend(type, value);
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Clear user identifier(s) for this agent.
|
|
1959
|
+
* Pass a specific type to clear only that identifier, or omit to clear both email and ID.
|
|
1960
|
+
*/
|
|
1961
|
+
clearUserIdentifier(type) {
|
|
1962
|
+
if (type) {
|
|
1963
|
+
if (type === "email" /* EMAIL */) {
|
|
1964
|
+
this.userEmail = void 0;
|
|
1965
|
+
} else {
|
|
1966
|
+
this.userId = void 0;
|
|
1967
|
+
}
|
|
1968
|
+
this.syncUserIdentifierToBackend(type, null);
|
|
1969
|
+
} else {
|
|
1970
|
+
this.userEmail = void 0;
|
|
1971
|
+
this.userId = void 0;
|
|
1972
|
+
this.syncUserIdentifierToBackend("email" /* EMAIL */, null);
|
|
1973
|
+
this.syncUserIdentifierToBackend("id" /* ID */, null);
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
syncUserIdentifierToBackend(type, value) {
|
|
1977
|
+
void this.post("/api/agent/update-user", {
|
|
1978
|
+
agent_id: this.agentID,
|
|
1979
|
+
identifier_type: type,
|
|
1980
|
+
identifier_value: value
|
|
1981
|
+
}).catch((err) => {
|
|
1982
|
+
console.error(`[PRBEAgent] Failed to sync user identifier: ${err}`);
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
2126
1985
|
/**
|
|
2127
1986
|
* Register a custom tool that the middleware can invoke during investigations.
|
|
2128
1987
|
*/
|
|
@@ -2131,58 +1990,92 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2131
1990
|
new PRBEClosureTool(name, description, parameters, handler, options)
|
|
2132
1991
|
);
|
|
2133
1992
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
this.currentInvestigationSource = "user" /* USER */;
|
|
2140
|
-
this.currentCRId = null;
|
|
2141
|
-
this.state.beginInvestigation(query);
|
|
1993
|
+
// ---------- Unified Investigation ----------
|
|
1994
|
+
async runInvestigation(opts) {
|
|
1995
|
+
this.currentInvestigationSource = opts.source;
|
|
1996
|
+
this.currentBackgroundId = opts.sourceId ?? null;
|
|
1997
|
+
const isBackground = opts.source !== "user" /* USER */;
|
|
2142
1998
|
const emitter = (status) => {
|
|
2143
1999
|
switch (status.type) {
|
|
2144
2000
|
case "started" /* STARTED */:
|
|
2145
|
-
|
|
2001
|
+
if (isBackground && opts.sourceId) {
|
|
2002
|
+
this.state.appendBackgroundEvent(opts.sourceId, "Starting investigation...");
|
|
2003
|
+
} else {
|
|
2004
|
+
this.state.appendEvent("Starting investigation...");
|
|
2005
|
+
}
|
|
2146
2006
|
break;
|
|
2147
2007
|
case "thinking" /* THINKING */:
|
|
2148
2008
|
break;
|
|
2149
2009
|
case "tool_call" /* TOOL_CALL */:
|
|
2150
|
-
|
|
2010
|
+
if (isBackground && opts.sourceId) {
|
|
2011
|
+
this.state.appendBackgroundEvent(opts.sourceId, status.label);
|
|
2012
|
+
} else {
|
|
2013
|
+
this.state.appendEvent(status.label);
|
|
2014
|
+
}
|
|
2151
2015
|
break;
|
|
2152
2016
|
case "observation" /* OBSERVATION */:
|
|
2153
|
-
|
|
2017
|
+
if (isBackground && opts.sourceId) {
|
|
2018
|
+
this.state.attachBackgroundObservation(opts.sourceId, status.text);
|
|
2019
|
+
} else {
|
|
2020
|
+
this.state.attachObservation(status.text);
|
|
2021
|
+
}
|
|
2154
2022
|
break;
|
|
2155
2023
|
case "thought" /* THOUGHT */:
|
|
2156
|
-
|
|
2024
|
+
if (isBackground && opts.sourceId) {
|
|
2025
|
+
this.state.appendBackgroundEvent(opts.sourceId, "Thinking", status.text);
|
|
2026
|
+
} else {
|
|
2027
|
+
this.state.appendEvent("Thinking", status.text);
|
|
2028
|
+
}
|
|
2157
2029
|
break;
|
|
2158
2030
|
case "completed" /* COMPLETED */:
|
|
2159
|
-
|
|
2160
|
-
|
|
2031
|
+
if (isBackground && opts.sourceId) {
|
|
2032
|
+
this.state.completeBackgroundInvestigation(opts.sourceId, status.report);
|
|
2033
|
+
} else {
|
|
2034
|
+
this.state.completeInvestigation(status.report, status.ticketId);
|
|
2035
|
+
}
|
|
2161
2036
|
break;
|
|
2162
2037
|
case "error" /* ERROR */:
|
|
2163
|
-
|
|
2038
|
+
if (isBackground && opts.sourceId) {
|
|
2039
|
+
this.state.failBackgroundInvestigation(opts.sourceId, status.message);
|
|
2040
|
+
} else {
|
|
2041
|
+
this.state.failInvestigation(status.message);
|
|
2042
|
+
}
|
|
2164
2043
|
break;
|
|
2165
2044
|
}
|
|
2166
2045
|
};
|
|
2167
2046
|
const result = await this.connectToProxy(
|
|
2168
|
-
query,
|
|
2169
|
-
|
|
2047
|
+
opts.query,
|
|
2048
|
+
opts.contextRequestId,
|
|
2049
|
+
opts.externalRequestId,
|
|
2050
|
+
opts.externalRequestSource,
|
|
2051
|
+
opts.externalRequestSourceDetail,
|
|
2170
2052
|
emitter,
|
|
2171
|
-
() => this.userCancelled
|
|
2053
|
+
opts.cancellable ? () => this.userCancelled : () => false,
|
|
2054
|
+
opts.ticketId
|
|
2172
2055
|
);
|
|
2173
2056
|
this.currentInvestigationSource = "user" /* USER */;
|
|
2174
|
-
this.
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2057
|
+
this.currentBackgroundId = null;
|
|
2058
|
+
return result;
|
|
2059
|
+
}
|
|
2060
|
+
/**
|
|
2061
|
+
* User-initiated investigation. Updates `state` events/report directly.
|
|
2062
|
+
*/
|
|
2063
|
+
async investigate(query, contextRequestID) {
|
|
2064
|
+
this.userCancelled = false;
|
|
2065
|
+
this.state.beginInvestigation(query);
|
|
2066
|
+
const result = await this.runInvestigation({
|
|
2067
|
+
query,
|
|
2068
|
+
source: "user" /* USER */,
|
|
2069
|
+
contextRequestId: contextRequestID,
|
|
2070
|
+
cancellable: true
|
|
2071
|
+
});
|
|
2072
|
+
if (!result && this.state.isInvestigating) {
|
|
2073
|
+
const message = this.userCancelled ? "Investigation cancelled" : "Investigation ended unexpectedly";
|
|
2074
|
+
this.state.failInvestigation(message);
|
|
2182
2075
|
}
|
|
2183
2076
|
}
|
|
2184
2077
|
/**
|
|
2185
|
-
* Cancel user-initiated investigation only (does not cancel background
|
|
2078
|
+
* Cancel user-initiated investigation only (does not cancel background investigations).
|
|
2186
2079
|
*/
|
|
2187
2080
|
cancelInvestigation() {
|
|
2188
2081
|
this.userCancelled = true;
|
|
@@ -2204,41 +2097,21 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2204
2097
|
this.stopPolling();
|
|
2205
2098
|
}
|
|
2206
2099
|
/**
|
|
2207
|
-
* Poll the backend for context requests
|
|
2208
|
-
* Resolves session IDs → ticket IDs first, then polls with ticket IDs.
|
|
2100
|
+
* Poll the backend for context requests and external requests.
|
|
2209
2101
|
*/
|
|
2210
2102
|
async poll() {
|
|
2211
|
-
const sessionIDs = this.trackedSessionIDs;
|
|
2212
|
-
if (sessionIDs.length === 0) return null;
|
|
2213
2103
|
try {
|
|
2214
|
-
const
|
|
2215
|
-
const
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
);
|
|
2221
|
-
const survivingSessions = sessionIDs.filter(
|
|
2222
|
-
(id) => returnedSessionIDs.has(id) && !resolvedSessionIDs.has(id)
|
|
2223
|
-
);
|
|
2224
|
-
if (survivingSessions.length !== sessionIDs.length) {
|
|
2225
|
-
this.trackedSessionIDs = survivingSessions;
|
|
2104
|
+
const request = { agent_id: this.agentID };
|
|
2105
|
+
const response = await this.post("/api/agent/poll", request);
|
|
2106
|
+
for (const cr of response.context_requests) {
|
|
2107
|
+
if (!cr.is_active) continue;
|
|
2108
|
+
if (this.state.activeBackgroundInvestigations.has(cr.id)) continue;
|
|
2109
|
+
await this.investigateForCR(cr, cr.ticket_id);
|
|
2226
2110
|
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
ticket_ids: ticketIDs
|
|
2232
|
-
};
|
|
2233
|
-
const response = await this.post(
|
|
2234
|
-
"/api/agent/poll",
|
|
2235
|
-
request
|
|
2236
|
-
);
|
|
2237
|
-
for (const ticket of response.tickets) {
|
|
2238
|
-
for (const cr of ticket.context_requests) {
|
|
2239
|
-
if (!cr.is_active) continue;
|
|
2240
|
-
await this.investigateForCR(cr, ticket.ticket_id);
|
|
2241
|
-
}
|
|
2111
|
+
for (const er of response.external_requests) {
|
|
2112
|
+
if (!er.is_active) continue;
|
|
2113
|
+
if (this.state.activeBackgroundInvestigations.has(er.id)) continue;
|
|
2114
|
+
await this.investigateForER(er);
|
|
2242
2115
|
}
|
|
2243
2116
|
return response;
|
|
2244
2117
|
} catch {
|
|
@@ -2246,25 +2119,18 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2246
2119
|
}
|
|
2247
2120
|
}
|
|
2248
2121
|
/**
|
|
2249
|
-
* Fetch
|
|
2250
|
-
* Resolves session IDs → ticket IDs first, then fetches ticket info.
|
|
2122
|
+
* Fetch agent history (tickets + sessions) from the backend.
|
|
2251
2123
|
*/
|
|
2252
|
-
async
|
|
2253
|
-
const sessionIDs = this.trackedSessionIDs;
|
|
2254
|
-
if (sessionIDs.length === 0) return [];
|
|
2124
|
+
async fetchHistory() {
|
|
2255
2125
|
try {
|
|
2256
|
-
const resolved = await this.resolveSessions(sessionIDs);
|
|
2257
|
-
const ticketIDs = resolved.tickets.map((t) => t.ticket_id);
|
|
2258
|
-
if (ticketIDs.length === 0) return [];
|
|
2259
|
-
const request = { ticket_ids: ticketIDs };
|
|
2260
2126
|
const response = await this.post(
|
|
2261
|
-
"/api/agent/
|
|
2262
|
-
|
|
2127
|
+
"/api/agent/history",
|
|
2128
|
+
{ agent_id: this.agentID }
|
|
2263
2129
|
);
|
|
2264
|
-
this.state.
|
|
2265
|
-
return response
|
|
2130
|
+
this.state.updateAgentHistory(response.tickets);
|
|
2131
|
+
return response;
|
|
2266
2132
|
} catch {
|
|
2267
|
-
return
|
|
2133
|
+
return null;
|
|
2268
2134
|
}
|
|
2269
2135
|
}
|
|
2270
2136
|
stopPolling() {
|
|
@@ -2274,7 +2140,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2274
2140
|
}
|
|
2275
2141
|
}
|
|
2276
2142
|
resumePolling() {
|
|
2277
|
-
if (this.
|
|
2143
|
+
if (!this.config.backgroundPolling) return;
|
|
2278
2144
|
this.startPolling();
|
|
2279
2145
|
}
|
|
2280
2146
|
/**
|
|
@@ -2292,13 +2158,11 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2292
2158
|
this.stopPolling();
|
|
2293
2159
|
this.persistedData = {};
|
|
2294
2160
|
savePersistedData(this.persistedData);
|
|
2295
|
-
HistoryStore.clear();
|
|
2296
2161
|
this.state.resetInvestigation();
|
|
2297
2162
|
this.state.completedInvestigations = [];
|
|
2298
|
-
this.state.
|
|
2299
|
-
this.state.
|
|
2300
|
-
this.state.
|
|
2301
|
-
this.state.ticketInfo = [];
|
|
2163
|
+
this.state.activeBackgroundInvestigations.clear();
|
|
2164
|
+
this.state.completedBackgroundInvestigations = [];
|
|
2165
|
+
this.state.agentHistory = [];
|
|
2302
2166
|
this.state.emit("status" /* STATUS */);
|
|
2303
2167
|
}
|
|
2304
2168
|
/**
|
|
@@ -2307,61 +2171,38 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2307
2171
|
static clearPersistedData() {
|
|
2308
2172
|
try {
|
|
2309
2173
|
const filePath = getPersistencePath();
|
|
2310
|
-
if (
|
|
2311
|
-
|
|
2174
|
+
if (fs2.existsSync(filePath)) {
|
|
2175
|
+
fs2.unlinkSync(filePath);
|
|
2312
2176
|
}
|
|
2313
|
-
HistoryStore.clear();
|
|
2314
2177
|
} catch {
|
|
2315
2178
|
}
|
|
2316
2179
|
}
|
|
2317
|
-
// ----------
|
|
2180
|
+
// ---------- Background Investigation ----------
|
|
2318
2181
|
async investigateForCR(cr, ticketId) {
|
|
2319
|
-
|
|
2320
|
-
this.
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
this.state.completeCR(crID, status.report);
|
|
2341
|
-
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2342
|
-
break;
|
|
2343
|
-
case "error" /* ERROR */:
|
|
2344
|
-
this.state.failCR(crID, status.message);
|
|
2345
|
-
this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
|
|
2346
|
-
break;
|
|
2347
|
-
}
|
|
2348
|
-
};
|
|
2349
|
-
const result = await this.connectToProxy(
|
|
2350
|
-
cr.query,
|
|
2351
|
-
crID,
|
|
2352
|
-
emitter,
|
|
2353
|
-
() => false,
|
|
2354
|
-
// CRs are not user-cancellable
|
|
2355
|
-
ticketId
|
|
2356
|
-
);
|
|
2357
|
-
this.currentInvestigationSource = "user" /* USER */;
|
|
2358
|
-
this.currentCRId = null;
|
|
2359
|
-
if (result?.sessionId) {
|
|
2360
|
-
this.addTrackedSession(result.sessionId);
|
|
2361
|
-
}
|
|
2182
|
+
this.state.beginBackgroundInvestigation(cr.id, cr.query, cr.slug ?? void 0, ticketId);
|
|
2183
|
+
await this.runInvestigation({
|
|
2184
|
+
query: cr.query,
|
|
2185
|
+
source: "context_request" /* CONTEXT_REQUEST */,
|
|
2186
|
+
sourceId: cr.id,
|
|
2187
|
+
contextRequestId: cr.id,
|
|
2188
|
+
ticketId,
|
|
2189
|
+
cancellable: false
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
async investigateForER(er) {
|
|
2193
|
+
this.state.beginBackgroundInvestigation(er.id, er.query, void 0, void 0, er.source, er.source_detail);
|
|
2194
|
+
await this.runInvestigation({
|
|
2195
|
+
query: er.query,
|
|
2196
|
+
source: "external_request" /* EXTERNAL_REQUEST */,
|
|
2197
|
+
sourceId: er.id,
|
|
2198
|
+
externalRequestId: er.id,
|
|
2199
|
+
externalRequestSource: er.source,
|
|
2200
|
+
externalRequestSourceDetail: er.source_detail,
|
|
2201
|
+
cancellable: false
|
|
2202
|
+
});
|
|
2362
2203
|
}
|
|
2363
2204
|
// ---------- WebSocket Investigation ----------
|
|
2364
|
-
connectToProxy(query, contextRequestID, emit, isCancelled, ticketId) {
|
|
2205
|
+
connectToProxy(query, contextRequestID, externalRequestId, externalRequestSource, externalRequestSourceDetail, emit, isCancelled, ticketId) {
|
|
2365
2206
|
return new Promise((resolve2) => {
|
|
2366
2207
|
const wsUrl = `${MIDDLEWARE_URL}/api/agent/client/ws`;
|
|
2367
2208
|
let uploadBaseUrl;
|
|
@@ -2416,15 +2257,25 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2416
2257
|
const startMetadata = {
|
|
2417
2258
|
agent_id: this.agentID,
|
|
2418
2259
|
custom_tools: toolDeclarations,
|
|
2419
|
-
platform:
|
|
2420
|
-
os_version:
|
|
2421
|
-
arch:
|
|
2260
|
+
platform: os.platform(),
|
|
2261
|
+
os_version: os.release(),
|
|
2262
|
+
arch: os.arch()
|
|
2422
2263
|
};
|
|
2423
2264
|
if (contextRequestID) startMetadata["context_request_id"] = contextRequestID;
|
|
2265
|
+
if (externalRequestId) startMetadata["external_request_id"] = externalRequestId;
|
|
2266
|
+
if (externalRequestSource) startMetadata["external_request_source"] = externalRequestSource;
|
|
2267
|
+
if (externalRequestSourceDetail) startMetadata["external_request_source_detail"] = externalRequestSourceDetail;
|
|
2424
2268
|
if (ticketId) startMetadata["ticket_id"] = ticketId;
|
|
2425
2269
|
if (this.appDataPath) startMetadata["app_data_path"] = this.appDataPath;
|
|
2426
|
-
|
|
2427
|
-
|
|
2270
|
+
const enrichedMetadata = { ...this.sessionMetadata };
|
|
2271
|
+
if (this.userEmail) {
|
|
2272
|
+
enrichedMetadata["user_email"] = this.userEmail;
|
|
2273
|
+
}
|
|
2274
|
+
if (this.userId) {
|
|
2275
|
+
enrichedMetadata["user_id"] = this.userId;
|
|
2276
|
+
}
|
|
2277
|
+
if (Object.keys(enrichedMetadata).length > 0) {
|
|
2278
|
+
startMetadata["session_metadata"] = enrichedMetadata;
|
|
2428
2279
|
}
|
|
2429
2280
|
if (!conn.send({ type: "start" /* START */, content: query, metadata: startMetadata })) {
|
|
2430
2281
|
emit({ type: "error" /* ERROR */, message: "Failed to send start message" });
|
|
@@ -2461,7 +2312,7 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2461
2312
|
const uploadPrefix = this.extractUploadPrefix(uploadBaseUrl);
|
|
2462
2313
|
const uploadedRefs = [];
|
|
2463
2314
|
for (const file of this.pendingFlaggedFiles) {
|
|
2464
|
-
const filename =
|
|
2315
|
+
const filename = path4.basename(file.originalPath);
|
|
2465
2316
|
const safeName = encodeURIComponent(filename);
|
|
2466
2317
|
const storagePath = `${uploadPrefix}/${safeName}`;
|
|
2467
2318
|
uploadedRefs.push({
|
|
@@ -2506,7 +2357,11 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2506
2357
|
case "conversation_update" /* CONVERSATION_UPDATE */: {
|
|
2507
2358
|
try {
|
|
2508
2359
|
const entry = JSON.parse(msg.content ?? "{}");
|
|
2509
|
-
this.
|
|
2360
|
+
if (this.currentInvestigationSource !== "user" /* USER */ && this.currentBackgroundId) {
|
|
2361
|
+
this.state.appendBackgroundConversation(this.currentBackgroundId, entry);
|
|
2362
|
+
} else {
|
|
2363
|
+
this.state.appendConversation(entry);
|
|
2364
|
+
}
|
|
2510
2365
|
} catch {
|
|
2511
2366
|
}
|
|
2512
2367
|
break;
|
|
@@ -2564,24 +2419,9 @@ var PRBEAgent = class _PRBEAgent {
|
|
|
2564
2419
|
startPolling() {
|
|
2565
2420
|
this.stopPolling();
|
|
2566
2421
|
this.pollingTimer = setInterval(() => {
|
|
2567
|
-
void this.poll()
|
|
2568
|
-
if (this.trackedSessionIDs.length === 0) {
|
|
2569
|
-
this.stopPolling();
|
|
2570
|
-
}
|
|
2571
|
-
});
|
|
2422
|
+
void this.poll();
|
|
2572
2423
|
}, this.config.pollingInterval);
|
|
2573
2424
|
}
|
|
2574
|
-
// ---------- Session Resolution ----------
|
|
2575
|
-
async resolveSessions(sessionIDs) {
|
|
2576
|
-
const request = {
|
|
2577
|
-
agent_id: this.agentID,
|
|
2578
|
-
session_ids: sessionIDs
|
|
2579
|
-
};
|
|
2580
|
-
return this.post(
|
|
2581
|
-
"/api/agent/resolve-sessions",
|
|
2582
|
-
request
|
|
2583
|
-
);
|
|
2584
|
-
}
|
|
2585
2425
|
// ---------- Networking ----------
|
|
2586
2426
|
/**
|
|
2587
2427
|
* Abort all in-flight fetch requests to prevent orphaned DNS lookups
|
|
@@ -2635,29 +2475,32 @@ var DEFAULT_PRBE_STATE = {
|
|
|
2635
2475
|
resolvedInteractions: [],
|
|
2636
2476
|
conversationHistory: [],
|
|
2637
2477
|
completedInvestigations: [],
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
trackedSessionIDs: [],
|
|
2478
|
+
activeBackgroundInvestigations: [],
|
|
2479
|
+
completedBackgroundInvestigations: [],
|
|
2641
2480
|
ticketInfo: [],
|
|
2481
|
+
agentHistory: [],
|
|
2642
2482
|
hasActiveWork: false
|
|
2643
2483
|
};
|
|
2644
|
-
function
|
|
2484
|
+
function serializeBackgroundInvestigation(bg) {
|
|
2645
2485
|
return {
|
|
2646
|
-
id:
|
|
2647
|
-
query:
|
|
2648
|
-
slug:
|
|
2649
|
-
ticketId:
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2486
|
+
id: bg.id,
|
|
2487
|
+
query: bg.query,
|
|
2488
|
+
slug: bg.slug,
|
|
2489
|
+
ticketId: bg.ticketId,
|
|
2490
|
+
source: bg.source,
|
|
2491
|
+
sourceDetail: bg.sourceDetail,
|
|
2492
|
+
events: bg.events,
|
|
2493
|
+
isRunning: bg.isRunning,
|
|
2494
|
+
isCompleted: bg.isCompleted,
|
|
2495
|
+
isFailed: bg.isFailed,
|
|
2496
|
+
report: bg.report,
|
|
2497
|
+
summary: bg.summary,
|
|
2498
|
+
errorMessage: bg.errorMessage,
|
|
2499
|
+
agentMessage: bg.agentMessage,
|
|
2500
|
+
startedAt: bg.startedAt.toISOString(),
|
|
2501
|
+
pendingInteraction: bg.pendingInteraction,
|
|
2502
|
+
resolvedInteractions: bg.resolvedInteractions ?? [],
|
|
2503
|
+
conversationHistory: bg.conversationHistory ?? []
|
|
2661
2504
|
};
|
|
2662
2505
|
}
|
|
2663
2506
|
function serializePRBEState(state) {
|
|
@@ -2683,10 +2526,10 @@ function serializePRBEState(state) {
|
|
|
2683
2526
|
conversationHistory: inv.conversationHistory,
|
|
2684
2527
|
completedAt: inv.completedAt.toISOString()
|
|
2685
2528
|
})),
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
trackedSessionIDs: state.trackedSessionIDs,
|
|
2529
|
+
activeBackgroundInvestigations: Array.from(state.activeBackgroundInvestigations.values()).map(serializeBackgroundInvestigation),
|
|
2530
|
+
completedBackgroundInvestigations: state.completedBackgroundInvestigations.map(serializeBackgroundInvestigation),
|
|
2689
2531
|
ticketInfo: state.ticketInfo,
|
|
2532
|
+
agentHistory: state.agentHistory,
|
|
2690
2533
|
hasActiveWork: state.hasActiveWork
|
|
2691
2534
|
};
|
|
2692
2535
|
}
|
|
@@ -2729,6 +2572,7 @@ export {
|
|
|
2729
2572
|
SearchContentTool,
|
|
2730
2573
|
ToolName,
|
|
2731
2574
|
ToolParamType,
|
|
2575
|
+
UserIdentifierType,
|
|
2732
2576
|
WSMessageType,
|
|
2733
2577
|
humanReadableSize,
|
|
2734
2578
|
redactPII,
|