@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.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  // package.json
2
- var version = "0.1.16";
2
+ var version = "0.1.18";
3
3
 
4
4
  // src/agent.ts
5
- import * as fs3 from "fs";
6
- import * as path5 from "path";
7
- import * as os2 from "os";
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["CR_START"] = "cr-start";
191
- PRBEStateEvent2["CR_COMPLETE"] = "cr-complete";
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
- activeCRs = /* @__PURE__ */ new Map();
215
- completedCRs = [];
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.activeCRs.size > 0;
228
+ return this.isInvestigating || this.activeBackgroundInvestigations.size > 0;
222
229
  }
223
- get activeCRCount() {
224
- return this.activeCRs.size;
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
- setCRPendingInteraction(crID, payload) {
322
- const cr = this.activeCRs.get(crID);
323
- if (!cr) return;
324
- cr.pendingInteraction = payload;
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
- clearCRPendingInteraction(crID) {
329
- const cr = this.activeCRs.get(crID);
330
- if (!cr) return;
331
- cr.pendingInteraction = void 0;
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
- resolveCRInteraction(crID, response) {
348
- const cr = this.activeCRs.get(crID);
349
- if (!cr || !cr.pendingInteraction) return;
350
- const resolved = cr.resolvedInteractions ?? [];
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: cr.pendingInteraction.interactionId,
353
- payload: cr.pendingInteraction,
365
+ interactionId: bg.pendingInteraction.interactionId,
366
+ payload: bg.pendingInteraction,
354
367
  response,
355
- eventIndex: cr.events.length
368
+ eventIndex: bg.events.length
356
369
  });
357
- cr.resolvedInteractions = resolved;
358
- cr.pendingInteraction = void 0;
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
- setCRAgentMessage(crID, message) {
368
- const cr = this.activeCRs.get(crID);
369
- if (!cr) return;
370
- cr.agentMessage = message;
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
- // ---------- CR state mutations ----------
382
- beginCR(id, query, slug, ticketId) {
383
- const cr = {
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.activeCRs.set(id, cr);
398
- this.emit("cr-start" /* CR_START */, cr);
413
+ this.activeBackgroundInvestigations.set(id, bg);
414
+ this.emit("background-start" /* BACKGROUND_START */, bg);
399
415
  this.emit("status" /* STATUS */);
400
416
  }
401
- appendCREvent(crID, label, detail, completed = false) {
402
- const cr = this.activeCRs.get(crID);
403
- if (!cr) return;
404
- if (cr.events.length > 0) {
405
- const last = cr.events[cr.events.length - 1];
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
- cr.events.push({
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
- attachCRObservation(crID, text) {
420
- const cr = this.activeCRs.get(crID);
421
- if (!cr || cr.events.length === 0) return;
422
- cr.events[cr.events.length - 1].detail = text;
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
- completeCR(id, report) {
426
- const cr = this.activeCRs.get(id);
427
- if (!cr) return;
428
- this.activeCRs.delete(id);
429
- if (cr.events.length > 0) {
430
- cr.events[cr.events.length - 1].isCompleted = true;
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
- cr.events.push({
448
+ bg.events.push({
433
449
  id: randomUUID(),
434
450
  label: "Done",
435
451
  isCompleted: true,
436
452
  isExpanded: false
437
453
  });
438
- cr.isRunning = false;
439
- cr.isCompleted = true;
440
- cr.report = report;
441
- this.completedCRs.unshift(cr);
442
- this.emit("cr-complete" /* CR_COMPLETE */, cr);
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
- failCR(id, message) {
446
- const cr = this.activeCRs.get(id);
447
- if (!cr) return;
448
- this.activeCRs.delete(id);
449
- cr.events.push({
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
- cr.isRunning = false;
456
- cr.isFailed = true;
457
- cr.errorMessage = message;
458
- this.completedCRs.unshift(cr);
459
- this.emit("cr-complete" /* CR_COMPLETE */, cr);
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/history.ts
1696
- import * as fs2 from "fs";
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
- return path4.join(appData, "prbe-agent");
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 (fs3.existsSync(filePath)) {
1885
- const raw = fs3.readFileSync(filePath, "utf-8");
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
- fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
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
- currentCRId = null;
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
- this.historyStore = new HistoryStore(this.config.apiKey);
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 === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
2008
- this.state.setCRAgentMessage(this.currentCRId, message);
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
- const existingSessions = this.trackedSessionIDs;
2026
- if (existingSessions.length > 0) {
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 === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
2082
- this.state.setCRPendingInteraction(this.currentCRId, payload);
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 === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
2089
- this.state.resolveCRInteraction(this.currentCRId, response);
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 === "context_request" /* CONTEXT_REQUEST */ && this.currentCRId) {
2103
- this.state.clearCRPendingInteraction(this.currentCRId);
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
- * User-initiated investigation. Updates `state` events/report directly.
2136
- */
2137
- async investigate(query, contextRequestID) {
2138
- this.userCancelled = false;
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
- this.state.appendEvent("Starting investigation...");
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
- this.state.appendEvent(status.label);
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
- this.state.attachObservation(status.text);
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
- this.state.appendEvent("Thinking", status.text);
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
- this.state.completeInvestigation(status.report, status.ticketId);
2160
- this.historyStore.save(this.state.completedInvestigations, this.state.completedCRs);
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
- this.state.failInvestigation(status.message);
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
- contextRequestID,
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.currentCRId = null;
2175
- if (result?.sessionId) {
2176
- this.addTrackedSession(result.sessionId);
2177
- } else if (!result) {
2178
- if (this.state.isInvestigating) {
2179
- const message = this.userCancelled ? "Investigation cancelled" : "Investigation ended unexpectedly";
2180
- this.state.failInvestigation(message);
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 CRs).
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 on tracked tickets.
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 resolved = await this.resolveSessions(sessionIDs);
2215
- const returnedSessionIDs = new Set(
2216
- resolved.tickets.flatMap((t) => t.session_ids)
2217
- );
2218
- const resolvedSessionIDs = new Set(
2219
- resolved.tickets.filter((t) => t.status === "resolved").flatMap((t) => t.session_ids)
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
- const ticketIDs = resolved.tickets.filter((t) => t.status !== "resolved").map((t) => t.ticket_id);
2228
- if (ticketIDs.length === 0) return { tickets: [] };
2229
- const request = {
2230
- agent_id: this.agentID,
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 ticket display info for all tracked sessions.
2250
- * Resolves session IDs → ticket IDs first, then fetches ticket info.
2122
+ * Fetch agent history (tickets + sessions) from the backend.
2251
2123
  */
2252
- async fetchTicketInfo() {
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/tickets",
2262
- request
2127
+ "/api/agent/history",
2128
+ { agent_id: this.agentID }
2263
2129
  );
2264
- this.state.updateTicketInfo(response.tickets);
2265
- return response.tickets;
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.trackedSessionIDs.length === 0) return;
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.activeCRs.clear();
2299
- this.state.completedCRs = [];
2300
- this.state.trackedSessionIDs = [];
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 (fs3.existsSync(filePath)) {
2311
- fs3.unlinkSync(filePath);
2174
+ if (fs2.existsSync(filePath)) {
2175
+ fs2.unlinkSync(filePath);
2312
2176
  }
2313
- HistoryStore.clear();
2314
2177
  } catch {
2315
2178
  }
2316
2179
  }
2317
- // ---------- CR Investigation ----------
2180
+ // ---------- Background Investigation ----------
2318
2181
  async investigateForCR(cr, ticketId) {
2319
- const crID = cr.id;
2320
- this.currentInvestigationSource = "context_request" /* CONTEXT_REQUEST */;
2321
- this.currentCRId = crID;
2322
- this.state.beginCR(crID, cr.query, cr.slug ?? void 0, ticketId);
2323
- const emitter = (status) => {
2324
- switch (status.type) {
2325
- case "started" /* STARTED */:
2326
- this.state.appendCREvent(crID, "Starting investigation...");
2327
- break;
2328
- case "thinking" /* THINKING */:
2329
- break;
2330
- case "tool_call" /* TOOL_CALL */:
2331
- this.state.appendCREvent(crID, status.label);
2332
- break;
2333
- case "observation" /* OBSERVATION */:
2334
- this.state.attachCRObservation(crID, status.text);
2335
- break;
2336
- case "thought" /* THOUGHT */:
2337
- this.state.appendCREvent(crID, "Thinking", status.text);
2338
- break;
2339
- case "completed" /* COMPLETED */:
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: os2.platform(),
2420
- os_version: os2.release(),
2421
- arch: os2.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
- if (Object.keys(this.sessionMetadata).length > 0) {
2427
- startMetadata["session_metadata"] = this.sessionMetadata;
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 = path5.basename(file.originalPath);
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.state.appendConversation(entry);
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().then(() => {
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
- activeCRs: [],
2639
- completedCRs: [],
2640
- trackedSessionIDs: [],
2478
+ activeBackgroundInvestigations: [],
2479
+ completedBackgroundInvestigations: [],
2641
2480
  ticketInfo: [],
2481
+ agentHistory: [],
2642
2482
  hasActiveWork: false
2643
2483
  };
2644
- function serializeCR(cr) {
2484
+ function serializeBackgroundInvestigation(bg) {
2645
2485
  return {
2646
- id: cr.id,
2647
- query: cr.query,
2648
- slug: cr.slug,
2649
- ticketId: cr.ticketId,
2650
- events: cr.events,
2651
- isRunning: cr.isRunning,
2652
- isCompleted: cr.isCompleted,
2653
- isFailed: cr.isFailed,
2654
- report: cr.report,
2655
- summary: cr.summary,
2656
- errorMessage: cr.errorMessage,
2657
- agentMessage: cr.agentMessage,
2658
- startedAt: cr.startedAt.toISOString(),
2659
- pendingInteraction: cr.pendingInteraction,
2660
- resolvedInteractions: cr.resolvedInteractions ?? []
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
- activeCRs: Array.from(state.activeCRs.values()).map(serializeCR),
2687
- completedCRs: state.completedCRs.map(serializeCR),
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,