@sentry/junior 0.122.1 → 0.124.0

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.
Files changed (78) hide show
  1. package/dist/{agent-hooks-65WXVKKX.js → agent-hooks-RPQRUAGN.js} +7 -7
  2. package/dist/api/conversations/detail.d.ts +55 -0
  3. package/dist/api/conversations/event-list.d.ts +55 -0
  4. package/dist/api/conversations/events.d.ts +1 -1
  5. package/dist/api/conversations/stats.d.ts +15 -0
  6. package/dist/api/schema/conversation.d.ts +260 -0
  7. package/dist/api/schema.d.ts +1 -1
  8. package/dist/api/schema.js +1 -1
  9. package/dist/api.js +137 -22
  10. package/dist/app.js +33 -20
  11. package/dist/{catalog-runtime-VNNMSKCB.js → catalog-runtime-QM2W6BBD.js} +5 -5
  12. package/dist/chat/agent/action-confirmation-retry.d.ts +6 -0
  13. package/dist/chat/agent/tools.d.ts +12 -0
  14. package/dist/chat/config.d.ts +1 -0
  15. package/dist/chat/conversations/history.d.ts +91 -1
  16. package/dist/chat/conversations/projection.d.ts +24 -0
  17. package/dist/chat/conversations/provenance.d.ts +2 -0
  18. package/dist/chat/conversations/structured-events.d.ts +31 -0
  19. package/dist/chat/mcp/tool-manager.d.ts +1 -1
  20. package/dist/chat/pi/client.d.ts +6 -0
  21. package/dist/chat/pi/sdk.d.ts +1 -1
  22. package/dist/chat/pi/transcript.d.ts +2 -0
  23. package/dist/chat/plugins/agent-hooks.d.ts +2 -0
  24. package/dist/chat/plugins/conversation-events.d.ts +15 -0
  25. package/dist/chat/services/guardian-action-policy.d.ts +12 -0
  26. package/dist/chat/services/guardian-action-review.d.ts +9 -0
  27. package/dist/chat/services/provider-error.d.ts +2 -0
  28. package/dist/chat/tool-support/action-review-evidence.d.ts +4 -0
  29. package/dist/chat/tool-support/action-review-history.d.ts +117 -0
  30. package/dist/chat/tool-support/action-review.d.ts +142 -0
  31. package/dist/chat/tool-support/pi-tool-adapter.d.ts +2 -1
  32. package/dist/chat/tool-support/skill/mcp-tool-summary.d.ts +1 -6
  33. package/dist/chat/tool-support/zod-tool.d.ts +1 -0
  34. package/dist/chat/tools/definition.d.ts +23 -1
  35. package/dist/chat/tools/query-conversation-events.d.ts +1 -1
  36. package/dist/chat/tools/search-tools.d.ts +0 -20
  37. package/dist/chat/tools/skill/search-mcp-tools.d.ts +0 -20
  38. package/dist/{chunk-73TQBD5S.js → chunk-4HQMMFRL.js} +1 -1
  39. package/dist/{chunk-3KYLHUVC.js → chunk-4OWSABFE.js} +1474 -593
  40. package/dist/{chunk-LZ4XXS76.js → chunk-7S36LUYT.js} +3 -2
  41. package/dist/{chunk-4ZV2GNHX.js → chunk-APPWCJVJ.js} +1 -1
  42. package/dist/{chunk-O2ULQJWR.js → chunk-AYQZCJZJ.js} +47 -1
  43. package/dist/{chunk-XBYNPBPQ.js → chunk-EKVBTUVM.js} +2 -2
  44. package/dist/{chunk-VLRECFIC.js → chunk-GBIFLB5Y.js} +57 -11
  45. package/dist/{chunk-MSDKKTRG.js → chunk-HOVHXQQE.js} +4 -4
  46. package/dist/{chunk-TI7SYDD4.js → chunk-IYUHOYFA.js} +68 -4
  47. package/dist/{chunk-HGREP4UX.js → chunk-MG3L3UGS.js} +1 -1
  48. package/dist/{chunk-GPQLJDT5.js → chunk-PBZEJRYY.js} +20 -20
  49. package/dist/{chunk-QE33ATQW.js → chunk-PGLSOXFU.js} +19 -11
  50. package/dist/{chunk-MU6HHZEN.js → chunk-PR3M62LK.js} +74 -0
  51. package/dist/{chunk-WFJ2EG4E.js → chunk-RW6MD6ZV.js} +1 -1
  52. package/dist/{chunk-IEE5CSAP.js → chunk-TFO4SDCQ.js} +1 -1
  53. package/dist/{chunk-PYS4QZAF.js → chunk-UZAOIEAR.js} +1 -1
  54. package/dist/{chunk-4JPJTFUH.js → chunk-VLAWZSCB.js} +9 -4
  55. package/dist/chunk-W4YS2LXS.js +55 -0
  56. package/dist/{chunk-U5PRRZMZ.js → chunk-WFIXN6UU.js} +7 -7
  57. package/dist/{chunk-BXT63TNS.js → chunk-WKLA6WLW.js} +77 -6
  58. package/dist/{chunk-M7KAZXTE.js → chunk-YYAQ5ZNK.js} +30 -2
  59. package/dist/{chunk-PXPBBOIU.js → chunk-ZV2K3WM4.js} +1 -1
  60. package/dist/cli/chat.js +22 -22
  61. package/dist/cli/check.js +6 -6
  62. package/dist/cli/init.js +2 -1
  63. package/dist/cli/plugins.js +10 -10
  64. package/dist/cli/snapshot-create.js +8 -8
  65. package/dist/cli/upgrade.js +5 -5
  66. package/dist/{db-36HXKAKH.js → db-2W4KOPLN.js} +5 -5
  67. package/dist/instrumentation.js +2 -2
  68. package/dist/nitro.js +2 -2
  69. package/dist/{oauth-callback-server-UKOO7KKP.js → oauth-callback-server-3TGRLQUD.js} +16 -15
  70. package/dist/{runner-M66KMCQ7.js → runner-NAVNNKQY.js} +11 -10
  71. package/dist/{skills-TTXTVFOG.js → skills-FIVS6EXW.js} +6 -6
  72. package/dist/{validation-TGASRGNN.js → validation-NX4DAKNV.js} +6 -6
  73. package/dist/version.js +1 -1
  74. package/migrations/0012_structured_conversation_events.sql +4 -0
  75. package/migrations/meta/0012_snapshot.json +1244 -0
  76. package/migrations/meta/_journal.json +7 -0
  77. package/package.json +7 -6
  78. package/dist/chat/tool-support/schema-summary.d.ts +0 -2
package/dist/api.js CHANGED
@@ -24,15 +24,18 @@ import {
24
24
  personalTokenParamsSchema,
25
25
  revokePersonalTokenResponseSchema,
26
26
  statsReportSchema
27
- } from "./chunk-O2ULQJWR.js";
27
+ } from "./chunk-AYQZCJZJ.js";
28
28
  import {
29
29
  formatSlackConversationRedactedLabel,
30
30
  readHealthReport,
31
31
  resolveSlackConversationContextFromThreadId
32
- } from "./chunk-PXPBBOIU.js";
32
+ } from "./chunk-ZV2K3WM4.js";
33
33
  import {
34
34
  buildSentryConversationUrl
35
35
  } from "./chunk-4CODA7P5.js";
36
+ import {
37
+ renderPluginConversationEvent
38
+ } from "./chunk-W4YS2LXS.js";
36
39
  import {
37
40
  healthReportSchema,
38
41
  pluginOperationalReportFeedSchema,
@@ -42,23 +45,24 @@ import {
42
45
  } from "./chunk-PE44LDDQ.js";
43
46
  import {
44
47
  readStats
45
- } from "./chunk-IEE5CSAP.js";
48
+ } from "./chunk-TFO4SDCQ.js";
46
49
  import {
47
50
  agentTurnUsageSchema,
48
- hasAgentTurnUsage
49
- } from "./chunk-MU6HHZEN.js";
51
+ hasAgentTurnUsage,
52
+ renderJuniorNativeConversationEvent
53
+ } from "./chunk-PR3M62LK.js";
50
54
  import "./chunk-PDO5BLNM.js";
51
55
  import {
52
56
  createPluginLogger,
53
57
  getPlugins,
54
58
  listConversationAnnotations,
55
59
  readViewerActors
56
- } from "./chunk-QE33ATQW.js";
60
+ } from "./chunk-PGLSOXFU.js";
57
61
  import {
58
62
  decodeStoredConversationEvent,
59
63
  getDb,
60
64
  getSqlExecutor
61
- } from "./chunk-M7KAZXTE.js";
65
+ } from "./chunk-YYAQ5ZNK.js";
62
66
  import {
63
67
  juniorApiTokens,
64
68
  juniorConversationEvents,
@@ -66,8 +70,8 @@ import {
66
70
  juniorIdentities,
67
71
  juniorUsers
68
72
  } from "./chunk-GCGJGSQL.js";
69
- import "./chunk-WFJ2EG4E.js";
70
- import "./chunk-TI7SYDD4.js";
73
+ import "./chunk-RW6MD6ZV.js";
74
+ import "./chunk-IYUHOYFA.js";
71
75
  import {
72
76
  juniorDestinations
73
77
  } from "./chunk-VFUK3X5B.js";
@@ -76,12 +80,12 @@ import {
76
80
  parseSlackThreadId
77
81
  } from "./chunk-S7G34U75.js";
78
82
  import "./chunk-HZF5P5UN.js";
79
- import "./chunk-4JPJTFUH.js";
83
+ import "./chunk-VLAWZSCB.js";
80
84
  import "./chunk-OB42YVAE.js";
81
85
  import "./chunk-F3B2YJ76.js";
82
86
  import "./chunk-6GWA276C.js";
83
- import "./chunk-PYS4QZAF.js";
84
- import "./chunk-LZ4XXS76.js";
87
+ import "./chunk-UZAOIEAR.js";
88
+ import "./chunk-7S36LUYT.js";
85
89
  import "./chunk-MLKGABMK.js";
86
90
 
87
91
  // src/api.ts
@@ -360,8 +364,10 @@ var conversationReportSourceEventTypes = [
360
364
  "assistant_message",
361
365
  "tool_result",
362
366
  "tool_execution_started",
367
+ "guardian_action_reviewed",
363
368
  "turn_started",
364
369
  "turn_context",
370
+ "structured_event",
365
371
  "turn_routed",
366
372
  "turn_completed",
367
373
  "turn_failed",
@@ -403,6 +409,11 @@ var reportingMediaPartSchema = z2.object({
403
409
  type: z2.enum(["image", "audio"]),
404
410
  mimeType: z2.string().min(1).optional()
405
411
  }).passthrough();
412
+ var reportingMessageAuthorSchema = z2.object({
413
+ fullName: z2.string().min(1).optional(),
414
+ userId: z2.string().min(1).optional(),
415
+ userName: z2.string().min(1).optional()
416
+ }).passthrough();
406
417
  function sanitizeModelContentPart(value) {
407
418
  const text = reportingTextPartSchema.safeParse(value);
408
419
  if (text.success) return { type: "text", text: text.data.text };
@@ -420,6 +431,17 @@ function modelVisibleToolOutput(content) {
420
431
  const only = sanitized[0];
421
432
  return only.type === "text" ? only.text : only;
422
433
  }
434
+ function reportMessageActorIdentity(data) {
435
+ if (data.role !== "user") return void 0;
436
+ const author = reportingMessageAuthorSchema.safeParse(data.meta?.author);
437
+ if (!author.success) return void 0;
438
+ const actorIdentity = {
439
+ ...author.data.fullName ? { fullName: author.data.fullName } : {},
440
+ ...author.data.userId ? { slackUserId: author.data.userId } : {},
441
+ ...author.data.userName ? { slackUserName: author.data.userName } : {}
442
+ };
443
+ return Object.keys(actorIdentity).length > 0 ? actorIdentity : void 0;
444
+ }
423
445
  function reportToolCalls(args) {
424
446
  const message2 = reportingAssistantMessageSchema.safeParse(args.message);
425
447
  if (!message2.success) return void 0;
@@ -514,15 +536,31 @@ function conversationReportToolResultIds(events) {
514
536
  }
515
537
  function reportEventData(args) {
516
538
  const { data } = args;
539
+ if (data.type === "structured_event") {
540
+ if (!args.canExposePayload) return void 0;
541
+ const presentation = data.namespace === "junior" ? renderJuniorNativeConversationEvent(data) : renderPluginConversationEvent(data);
542
+ if (!presentation) return void 0;
543
+ return {
544
+ type: "structured_event",
545
+ namespace: data.namespace,
546
+ name: data.name,
547
+ version: data.version,
548
+ ...data.turnId ? { turnId: data.turnId } : {},
549
+ presentation
550
+ };
551
+ }
517
552
  switch (data.type) {
518
- case "message":
553
+ case "message": {
554
+ const actorIdentity = args.canExposePayload ? reportMessageActorIdentity(data) : void 0;
519
555
  return {
520
556
  type: "message",
521
557
  messageId: data.messageId,
522
558
  role: data.role,
559
+ ...actorIdentity ? { actorIdentity } : {},
523
560
  ...typeof data.meta?.eventType === "string" ? { eventType: data.meta.eventType } : {},
524
561
  ...args.canExposePayload ? { text: data.text } : { redacted: true }
525
562
  };
563
+ }
526
564
  case "message_handled":
527
565
  return {
528
566
  type: "message_handled",
@@ -556,6 +594,16 @@ function reportEventData(args) {
556
594
  ...data.confidence !== void 0 ? { confidence: data.confidence } : {},
557
595
  source: data.source
558
596
  };
597
+ case "guardian_action_reviewed":
598
+ return {
599
+ type: "guardian_action_reviewed",
600
+ turnId: data.turnId,
601
+ toolCallId: data.toolCallId,
602
+ toolName: data.toolName,
603
+ decision: data.decision,
604
+ riskLevel: data.riskLevel,
605
+ userAuthorization: data.userAuthorization
606
+ };
559
607
  case "turn_completed":
560
608
  return {
561
609
  type: "turn_lifecycle",
@@ -1589,6 +1637,46 @@ function metricDays(rows, endMs) {
1589
1637
  }
1590
1638
  return days;
1591
1639
  }
1640
+ function guardianStats(rows, endMs) {
1641
+ const byDate = new Map(rows.map((row) => [row.date, row]));
1642
+ const end = new Date(endMs);
1643
+ end.setUTCHours(0, 0, 0, 0);
1644
+ const start = new Date(end);
1645
+ start.setUTCDate(start.getUTCDate() - (WINDOW_DAYS - 1));
1646
+ const metricDays2 = [];
1647
+ let allow = 0;
1648
+ let ask = 0;
1649
+ let deny = 0;
1650
+ let requests = 0;
1651
+ let costUsd;
1652
+ for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
1653
+ const date = cursor.toISOString().slice(0, 10);
1654
+ const row = byDate.get(date);
1655
+ allow += row?.allow ?? 0;
1656
+ ask += row?.ask ?? 0;
1657
+ deny += row?.deny ?? 0;
1658
+ requests += row?.requests ?? 0;
1659
+ if (row?.costUsd !== null && row?.costUsd !== void 0) {
1660
+ costUsd = addUsd(costUsd, row.costUsd);
1661
+ }
1662
+ metricDays2.push({
1663
+ allow: row?.allow ?? 0,
1664
+ ask: row?.ask ?? 0,
1665
+ date,
1666
+ deny: row?.deny ?? 0,
1667
+ requests: row?.requests ?? 0,
1668
+ ...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: row.costUsd } : {}
1669
+ });
1670
+ }
1671
+ return {
1672
+ allow,
1673
+ ask,
1674
+ deny,
1675
+ metricDays: metricDays2,
1676
+ requests,
1677
+ ...costUsd !== void 0 ? { costUsd } : {}
1678
+ };
1679
+ }
1592
1680
  async function aggregateStats(db, start, end) {
1593
1681
  const where = statsWhere(start, end);
1594
1682
  const activityDate = sql5`TO_CHAR(
@@ -1668,14 +1756,40 @@ async function aggregateStats(db, start, end) {
1668
1756
  ]);
1669
1757
  return { actorRows, locationRows, metricRows, totals: totalsRows[0] };
1670
1758
  }
1759
+ async function aggregateGuardianStats(db, start, end) {
1760
+ const date = sql5`TO_CHAR(
1761
+ ${juniorConversationEvents.createdAt} AT TIME ZONE 'UTC',
1762
+ 'YYYY-MM-DD'
1763
+ )`;
1764
+ const decision = sql5`${juniorConversationEvents.payload}->>'decision'`;
1765
+ const cost2 = sql5`CASE
1766
+ WHEN jsonb_typeof(${juniorConversationEvents.payload}->'costUsd') = 'number'
1767
+ THEN (${juniorConversationEvents.payload}->>'costUsd')::double precision
1768
+ ELSE NULL
1769
+ END`;
1770
+ return await db.select({
1771
+ allow: sql5`COUNT(*) FILTER (WHERE ${decision} = 'allow')::integer`,
1772
+ ask: sql5`COUNT(*) FILTER (WHERE ${decision} = 'ask')::integer`,
1773
+ costUsd: sql5`SUM(${cost2})::double precision`,
1774
+ date,
1775
+ deny: sql5`COUNT(*) FILTER (WHERE ${decision} = 'deny')::integer`,
1776
+ requests: sql5`COUNT(*)::integer`
1777
+ }).from(juniorConversationEvents).where(
1778
+ and6(
1779
+ eq7(juniorConversationEvents.type, "guardian_action_reviewed"),
1780
+ gte(juniorConversationEvents.createdAt, start),
1781
+ lte(juniorConversationEvents.createdAt, end)
1782
+ )
1783
+ ).groupBy(date);
1784
+ }
1671
1785
  async function readConversationStatsFromSql() {
1672
1786
  const nowMs = Date.now();
1673
1787
  const { end, start } = statsWindow(nowMs);
1674
- const { actorRows, locationRows, metricRows, totals } = await aggregateStats(
1675
- getDb(),
1676
- start,
1677
- end
1678
- );
1788
+ const db = getDb();
1789
+ const [{ actorRows, locationRows, metricRows, totals }, guardianRows] = await Promise.all([
1790
+ aggregateStats(db, start, end),
1791
+ aggregateGuardianStats(db, start, end)
1792
+ ]);
1679
1793
  const actors = /* @__PURE__ */ new Map();
1680
1794
  const locations = /* @__PURE__ */ new Map();
1681
1795
  for (const row of actorRows) {
@@ -1690,6 +1804,7 @@ async function readConversationStatsFromSql() {
1690
1804
  durationMs: totals?.durationMs ?? 0,
1691
1805
  failed: totals?.failed ?? 0,
1692
1806
  generatedAt: new Date(nowMs).toISOString(),
1807
+ guardian: guardianStats(guardianRows, nowMs),
1693
1808
  metricDays: metricDays(metricRows, nowMs),
1694
1809
  locations: statsItems(locations),
1695
1810
  actors: statsItems(actors),
@@ -1740,7 +1855,7 @@ function readDescriptionText(home) {
1740
1855
  }
1741
1856
  }
1742
1857
  async function readSkillReports() {
1743
- const { discoverSkills } = await import("./skills-TTXTVFOG.js");
1858
+ const { discoverSkills } = await import("./skills-FIVS6EXW.js");
1744
1859
  const skills = await discoverSkills();
1745
1860
  return skillReportsSchema.parse(
1746
1861
  skills.map((skill) => ({
@@ -1750,7 +1865,7 @@ async function readSkillReports() {
1750
1865
  );
1751
1866
  }
1752
1867
  async function readPlugins() {
1753
- const { pluginCatalogRuntime } = await import("./catalog-runtime-VNNMSKCB.js");
1868
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-QM2W6BBD.js");
1754
1869
  return pluginsSchema.parse(
1755
1870
  pluginCatalogRuntime.getProviders().map((plugin) => ({
1756
1871
  configKeys: plugin.manifest.configKeys ?? [],
@@ -1763,7 +1878,7 @@ async function readPlugins() {
1763
1878
  async function readRuntimeInfoReport() {
1764
1879
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
1765
1880
  import("./discovery-GUFTFBTL.js"),
1766
- import("./catalog-runtime-VNNMSKCB.js"),
1881
+ import("./catalog-runtime-QM2W6BBD.js"),
1767
1882
  readPlugins(),
1768
1883
  readSkillReports()
1769
1884
  ]);
@@ -1779,7 +1894,7 @@ async function readRuntimeInfoReport() {
1779
1894
  }
1780
1895
  async function readPluginOperationalReportFeed() {
1781
1896
  const nowMs = Date.now();
1782
- const { getPluginOperationalReports } = await import("./agent-hooks-65WXVKKX.js");
1897
+ const { getPluginOperationalReports } = await import("./agent-hooks-RPQRUAGN.js");
1783
1898
  return pluginOperationalReportFeedSchema.parse({
1784
1899
  source: "plugins",
1785
1900
  generatedAt: new Date(nowMs).toISOString(),
package/dist/app.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  startConversationWork,
51
51
  startSlackProcessingReaction,
52
52
  stripLeadingBotMention
53
- } from "./chunk-VLRECFIC.js";
53
+ } from "./chunk-GBIFLB5Y.js";
54
54
  import "./chunk-FA6POGLH.js";
55
55
  import {
56
56
  ConversationTurnLifecycleService,
@@ -65,14 +65,15 @@ import {
65
65
  processPluginTask,
66
66
  requireTurnFailureEventId,
67
67
  scheduleSessionCompletedPluginTasks
68
- } from "./chunk-GPQLJDT5.js";
68
+ } from "./chunk-PBZEJRYY.js";
69
69
  import {
70
70
  GET,
71
71
  conversationVisibilityFromSlackChannelType,
72
72
  resolveSlackChannelTypeFromMessage,
73
73
  resolveSlackConversationContext
74
- } from "./chunk-PXPBBOIU.js";
74
+ } from "./chunk-ZV2K3WM4.js";
75
75
  import "./chunk-4CODA7P5.js";
76
+ import "./chunk-W4YS2LXS.js";
76
77
  import "./chunk-PE44LDDQ.js";
77
78
  import {
78
79
  ConversationQueueMessageRejectedError,
@@ -90,7 +91,7 @@ import {
90
91
  import {
91
92
  validatePluginEgressCredentialHooks,
92
93
  validatePluginRegistrations
93
- } from "./chunk-HGREP4UX.js";
94
+ } from "./chunk-MG3L3UGS.js";
94
95
  import {
95
96
  defineJuniorPlugins,
96
97
  pluginCatalogConfigFromEnv,
@@ -123,7 +124,7 @@ import {
123
124
  setConfigDefaults,
124
125
  shouldEmitDevAgentTrace,
125
126
  shouldPropagateSandboxEgressTrace
126
- } from "./chunk-3KYLHUVC.js";
127
+ } from "./chunk-4OWSABFE.js";
127
128
  import "./chunk-DIB4GX3G.js";
128
129
  import {
129
130
  RetryableDeliveryError,
@@ -134,7 +135,7 @@ import {
134
135
  formatProviderLabel,
135
136
  postSlackMessage,
136
137
  startOAuthFlow
137
- } from "./chunk-U5PRRZMZ.js";
138
+ } from "./chunk-WFIXN6UU.js";
138
139
  import {
139
140
  ConversationTurnBoundaryError,
140
141
  CooperativeTurnYieldError,
@@ -190,11 +191,11 @@ import {
190
191
  trimTrailingAssistantMessages,
191
192
  updateConversationStats,
192
193
  upsertConversationMessage
193
- } from "./chunk-BXT63TNS.js";
194
+ } from "./chunk-WKLA6WLW.js";
194
195
  import "./chunk-HDSDCEPK.js";
195
- import "./chunk-MSDKKTRG.js";
196
- import "./chunk-IEE5CSAP.js";
197
- import "./chunk-MU6HHZEN.js";
196
+ import "./chunk-HOVHXQQE.js";
197
+ import "./chunk-TFO4SDCQ.js";
198
+ import "./chunk-PR3M62LK.js";
198
199
  import "./chunk-PDO5BLNM.js";
199
200
  import "./chunk-UIE3R5XU.js";
200
201
  import {
@@ -218,7 +219,7 @@ import {
218
219
  validatePlugins,
219
220
  verifyScheduledTaskCredentialSubject,
220
221
  verifySlackDirectCredentialSubject
221
- } from "./chunk-QE33ATQW.js";
222
+ } from "./chunk-PGLSOXFU.js";
222
223
  import {
223
224
  contextProvenance,
224
225
  createSlackDestination,
@@ -229,7 +230,7 @@ import {
229
230
  instructionProvenanceFor,
230
231
  requireSlackDestination,
231
232
  withConversationEventLock
232
- } from "./chunk-M7KAZXTE.js";
233
+ } from "./chunk-YYAQ5ZNK.js";
233
234
  import {
234
235
  juniorConversationEvents,
235
236
  juniorConversations
@@ -238,7 +239,7 @@ import {
238
239
  acquireActiveLock,
239
240
  getStateAdapter,
240
241
  sleep
241
- } from "./chunk-WFJ2EG4E.js";
242
+ } from "./chunk-RW6MD6ZV.js";
242
243
  import {
243
244
  STANDARD_MODEL_PROFILE,
244
245
  botConfig,
@@ -256,18 +257,18 @@ import {
256
257
  modelIdForProfile,
257
258
  setSlackReactionConfig,
258
259
  standardModelId
259
- } from "./chunk-TI7SYDD4.js";
260
+ } from "./chunk-IYUHOYFA.js";
260
261
  import {
261
262
  juniorDestinations
262
263
  } from "./chunk-VFUK3X5B.js";
263
264
  import {
264
265
  parseSlackThreadId
265
266
  } from "./chunk-S7G34U75.js";
266
- import "./chunk-XBYNPBPQ.js";
267
+ import "./chunk-EKVBTUVM.js";
267
268
  import {
268
269
  pluginCatalogRuntime
269
- } from "./chunk-73TQBD5S.js";
270
- import "./chunk-4ZV2GNHX.js";
270
+ } from "./chunk-4HQMMFRL.js";
271
+ import "./chunk-APPWCJVJ.js";
271
272
  import {
272
273
  credentialSubjectSchema
273
274
  } from "./chunk-W3U3YQYI.js";
@@ -294,7 +295,7 @@ import {
294
295
  withContext,
295
296
  withLogContext,
296
297
  withSpan
297
- } from "./chunk-4JPJTFUH.js";
298
+ } from "./chunk-VLAWZSCB.js";
298
299
  import {
299
300
  toOptionalString
300
301
  } from "./chunk-OB42YVAE.js";
@@ -309,10 +310,10 @@ import "./chunk-OOUNJNMR.js";
309
310
  import "./chunk-H4HBKISO.js";
310
311
  import {
311
312
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
312
- } from "./chunk-PYS4QZAF.js";
313
+ } from "./chunk-UZAOIEAR.js";
313
314
  import {
314
315
  JUNIOR_VERSION
315
- } from "./chunk-LZ4XXS76.js";
316
+ } from "./chunk-7S36LUYT.js";
316
317
  import "./chunk-MLKGABMK.js";
317
318
 
318
319
  // src/app.ts
@@ -4586,6 +4587,7 @@ var ROUTER_CLASSIFIER_MAX_TOKENS = 240;
4586
4587
  var LEADING_SLACK_MENTION_RE = /^\s*<@([A-Z0-9]+)(?:\|([^>]+))?>[\s,:-]*/i;
4587
4588
  var LEADING_NAMED_MENTION_RE = /^\s*@([a-z0-9._-]+)\b[\s,:-]*/i;
4588
4589
  var TRANSCRIPT_MESSAGE_LINE_RE = /^\[(assistant|system|user)\]\s+([^:]+):\s+([\s\S]+)$/i;
4590
+ var FORCED_THREAD_OPTOUT_RE = /^!stop(?:\s|$)/i;
4589
4591
  var THREAD_OPTOUT_PATTERNS = [
4590
4592
  /\bstop (?:watching|replying|participating)\b/i,
4591
4593
  /\bstay out\b/i,
@@ -4629,6 +4631,9 @@ function detectLeadingOtherPartyAddress(rawText, text, botUserName) {
4629
4631
  }
4630
4632
  return `named_mention:${directedName}`;
4631
4633
  }
4634
+ function isForcedThreadOptOutCommand(rawText, text) {
4635
+ return FORCED_THREAD_OPTOUT_RE.test(rawText.trim()) || FORCED_THREAD_OPTOUT_RE.test(text.trim());
4636
+ }
4632
4637
  function isThreadOptOutInstruction(rawText, text) {
4633
4638
  return THREAD_OPTOUT_PATTERNS.some(
4634
4639
  (pattern) => pattern.test(rawText) || pattern.test(text)
@@ -4788,6 +4793,14 @@ function buildRouterSystemPrompt(botUserName) {
4788
4793
  async function decideSubscribedThreadReply(args) {
4789
4794
  const text = args.input.text.trim();
4790
4795
  const rawText = args.input.rawText.trim();
4796
+ if (isForcedThreadOptOutCommand(rawText, text)) {
4797
+ return {
4798
+ shouldReply: false,
4799
+ shouldUnsubscribe: true,
4800
+ reason: "thread_opt_out" /* ThreadOptOut */,
4801
+ reasonDetail: "forced !stop command"
4802
+ };
4803
+ }
4791
4804
  const preflightDecision = getSubscribedReplyPreflightDecision({
4792
4805
  botUserName: args.botUserName,
4793
4806
  rawText,
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-73TQBD5S.js";
4
- import "./chunk-4ZV2GNHX.js";
3
+ } from "./chunk-4HQMMFRL.js";
4
+ import "./chunk-APPWCJVJ.js";
5
5
  import "./chunk-W3U3YQYI.js";
6
6
  import "./chunk-HZF5P5UN.js";
7
- import "./chunk-4JPJTFUH.js";
7
+ import "./chunk-VLAWZSCB.js";
8
8
  import "./chunk-OB42YVAE.js";
9
9
  import "./chunk-F3B2YJ76.js";
10
10
  import "./chunk-6GWA276C.js";
11
11
  import "./chunk-OOUNJNMR.js";
12
12
  import "./chunk-H4HBKISO.js";
13
- import "./chunk-PYS4QZAF.js";
14
- import "./chunk-LZ4XXS76.js";
13
+ import "./chunk-UZAOIEAR.js";
14
+ import "./chunk-7S36LUYT.js";
15
15
  import "./chunk-MLKGABMK.js";
16
16
  export {
17
17
  pluginCatalogRuntime
@@ -0,0 +1,6 @@
1
+ import type { PiMessage } from "@/chat/pi/messages";
2
+ /**
3
+ * Return the durable tool-result boundary for one additional agent
4
+ * continuation when an ask rejection has no destination-visible reply.
5
+ */
6
+ export declare function actionConfirmationRetryMessages(messages: readonly PiMessage[]): PiMessage[] | undefined;
@@ -33,6 +33,12 @@ interface ToolWiringArgs {
33
33
  currentActor?: Actor;
34
34
  /** Live projection of the run's committed instruction-authority actors so far. */
35
35
  currentActors?: () => Actor[];
36
+ /** Live Pi transcript used to give Guardian bounded action context. */
37
+ currentAgentMessages: () => PiMessage[];
38
+ /** Durable transcript for this turn only, used to restore rejection state. */
39
+ currentTurnMessages: readonly PiMessage[];
40
+ /** Live same-actor instructions that authorize the pending action. */
41
+ currentUserIntent: () => string;
36
42
  artifactStatePatch: Partial<ThreadArtifactsState>;
37
43
  availableSkills: SkillMetadata[];
38
44
  configurationValues: Record<string, unknown>;
@@ -43,6 +49,7 @@ interface ToolWiringArgs {
43
49
  generatedFiles: FileUpload[];
44
50
  invokedSkill: SkillMetadata | null;
45
51
  observers: AgentRunObservers;
52
+ onFatalToolError(error: Error): void;
46
53
  onSandboxRefChanged: (sandboxRef: SandboxRef) => void;
47
54
  policy: AgentRunPolicy;
48
55
  preAgentPromptMessages: () => PiMessage[];
@@ -68,6 +75,11 @@ export interface ToolWiring {
68
75
  getPendingAuthPause: () => AuthorizationPauseError | undefined;
69
76
  mcpToolManager: McpToolManager;
70
77
  pluginHooks: PluginHookRunner;
78
+ /** Project core-owned review state into one durable Pi tool result. */
79
+ projectActionReviewResult<TResult extends {
80
+ details?: unknown;
81
+ isError?: boolean;
82
+ }>(toolCallId: string, result: TResult): TResult;
71
83
  getSandboxRef: () => SandboxRef | undefined;
72
84
  close(): Promise<void>;
73
85
  toolGuidance: Array<{
@@ -12,6 +12,7 @@ export interface BotConfig {
12
12
  crossActorMidRunMode: CrossActorMidRunMode;
13
13
  embeddingModelId: string;
14
14
  fastModelId: string;
15
+ guardianModelId: string;
15
16
  imageGenerationModelId: string;
16
17
  loadingMessages: string[];
17
18
  profiles: Readonly<Record<string, ExecutionProfileConfig>>;
@@ -223,6 +223,29 @@ export declare const conversationEventDataSchema: z.ZodUnion<readonly [z.ZodUnio
223
223
  type: z.ZodLiteral<"tool_execution_started">;
224
224
  toolCallId: z.ZodString;
225
225
  toolName: z.ZodString;
226
+ }, z.core.$strict>, z.ZodObject<{
227
+ type: z.ZodLiteral<"guardian_action_reviewed">;
228
+ turnId: z.ZodString;
229
+ toolCallId: z.ZodString;
230
+ toolName: z.ZodString;
231
+ costUsd: z.ZodOptional<z.ZodNumber>;
232
+ decision: z.ZodEnum<{
233
+ allow: "allow";
234
+ ask: "ask";
235
+ deny: "deny";
236
+ }>;
237
+ riskLevel: z.ZodEnum<{
238
+ low: "low";
239
+ medium: "medium";
240
+ high: "high";
241
+ critical: "critical";
242
+ }>;
243
+ userAuthorization: z.ZodEnum<{
244
+ unknown: "unknown";
245
+ low: "low";
246
+ medium: "medium";
247
+ high: "high";
248
+ }>;
226
249
  }, z.core.$strict>, z.ZodObject<{
227
250
  type: z.ZodLiteral<"message_handled">;
228
251
  messageId: z.ZodString;
@@ -252,6 +275,13 @@ export declare const conversationEventDataSchema: z.ZodUnion<readonly [z.ZodUnio
252
275
  kind: z.ZodString;
253
276
  version: z.ZodNumber;
254
277
  content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
278
+ }, z.core.$strict>, z.ZodObject<{
279
+ type: z.ZodLiteral<"structured_event">;
280
+ namespace: z.ZodString;
281
+ name: z.ZodString;
282
+ version: z.ZodNumber;
283
+ turnId: z.ZodOptional<z.ZodString>;
284
+ content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
255
285
  }, z.core.$strict>, z.ZodObject<{
256
286
  type: z.ZodLiteral<"turn_routed">;
257
287
  turnId: z.ZodString;
@@ -392,7 +422,7 @@ export declare const conversationEventDataSchema: z.ZodUnion<readonly [z.ZodUnio
392
422
  /** One durable conversation event's validated data. */
393
423
  export type ConversationEventData = z.output<typeof conversationEventDataSchema>;
394
424
  /** Event type names recognized by current readers and observational queries. */
395
- export declare const KNOWN_CONVERSATION_EVENT_TYPES: readonly ["message", "message_updated", "user_message", "assistant_message", "tool_result", "mcp_provider_connected", "authorization_requested", "authorization_completed", "tool_execution_started", "message_handled", "messages_summarized", "turn_started", "turn_context", "turn_routed", "turn_completed", "turn_failed", "subagent_started", "subagent_ended", "handoff", "compaction"];
425
+ export declare const KNOWN_CONVERSATION_EVENT_TYPES: readonly ["message", "message_updated", "user_message", "assistant_message", "tool_result", "mcp_provider_connected", "authorization_requested", "authorization_completed", "tool_execution_started", "guardian_action_reviewed", "message_handled", "messages_summarized", "turn_started", "turn_context", "structured_event", "turn_routed", "turn_completed", "turn_failed", "subagent_started", "subagent_ended", "handoff", "compaction"];
396
426
  /** One known durable conversation event type name. */
397
427
  export type KnownConversationEventType = (typeof KNOWN_CONVERSATION_EVENT_TYPES)[number];
398
428
  declare const unknownConversationEventDataSchema: z.ZodObject<{
@@ -475,6 +505,29 @@ export declare const conversationEventSchema: z.ZodUnion<readonly [z.ZodObject<{
475
505
  type: z.ZodLiteral<"tool_execution_started">;
476
506
  toolCallId: z.ZodString;
477
507
  toolName: z.ZodString;
508
+ }, z.core.$strict>, z.ZodObject<{
509
+ type: z.ZodLiteral<"guardian_action_reviewed">;
510
+ turnId: z.ZodString;
511
+ toolCallId: z.ZodString;
512
+ toolName: z.ZodString;
513
+ costUsd: z.ZodOptional<z.ZodNumber>;
514
+ decision: z.ZodEnum<{
515
+ allow: "allow";
516
+ ask: "ask";
517
+ deny: "deny";
518
+ }>;
519
+ riskLevel: z.ZodEnum<{
520
+ low: "low";
521
+ medium: "medium";
522
+ high: "high";
523
+ critical: "critical";
524
+ }>;
525
+ userAuthorization: z.ZodEnum<{
526
+ unknown: "unknown";
527
+ low: "low";
528
+ medium: "medium";
529
+ high: "high";
530
+ }>;
478
531
  }, z.core.$strict>, z.ZodObject<{
479
532
  type: z.ZodLiteral<"message_handled">;
480
533
  messageId: z.ZodString;
@@ -504,6 +557,13 @@ export declare const conversationEventSchema: z.ZodUnion<readonly [z.ZodObject<{
504
557
  kind: z.ZodString;
505
558
  version: z.ZodNumber;
506
559
  content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
560
+ }, z.core.$strict>, z.ZodObject<{
561
+ type: z.ZodLiteral<"structured_event">;
562
+ namespace: z.ZodString;
563
+ name: z.ZodString;
564
+ version: z.ZodNumber;
565
+ turnId: z.ZodOptional<z.ZodString>;
566
+ content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
507
567
  }, z.core.$strict>, z.ZodObject<{
508
568
  type: z.ZodLiteral<"turn_routed">;
509
569
  turnId: z.ZodString;
@@ -750,6 +810,29 @@ export declare const newConversationEventSchema: z.ZodObject<{
750
810
  type: z.ZodLiteral<"tool_execution_started">;
751
811
  toolCallId: z.ZodString;
752
812
  toolName: z.ZodString;
813
+ }, z.core.$strict>, z.ZodObject<{
814
+ type: z.ZodLiteral<"guardian_action_reviewed">;
815
+ turnId: z.ZodString;
816
+ toolCallId: z.ZodString;
817
+ toolName: z.ZodString;
818
+ costUsd: z.ZodOptional<z.ZodNumber>;
819
+ decision: z.ZodEnum<{
820
+ allow: "allow";
821
+ ask: "ask";
822
+ deny: "deny";
823
+ }>;
824
+ riskLevel: z.ZodEnum<{
825
+ low: "low";
826
+ medium: "medium";
827
+ high: "high";
828
+ critical: "critical";
829
+ }>;
830
+ userAuthorization: z.ZodEnum<{
831
+ unknown: "unknown";
832
+ low: "low";
833
+ medium: "medium";
834
+ high: "high";
835
+ }>;
753
836
  }, z.core.$strict>, z.ZodObject<{
754
837
  type: z.ZodLiteral<"message_handled">;
755
838
  messageId: z.ZodString;
@@ -779,6 +862,13 @@ export declare const newConversationEventSchema: z.ZodObject<{
779
862
  kind: z.ZodString;
780
863
  version: z.ZodNumber;
781
864
  content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
865
+ }, z.core.$strict>, z.ZodObject<{
866
+ type: z.ZodLiteral<"structured_event">;
867
+ namespace: z.ZodString;
868
+ name: z.ZodString;
869
+ version: z.ZodNumber;
870
+ turnId: z.ZodOptional<z.ZodString>;
871
+ content: z.ZodRecord<z.ZodString, z.ZodUnknown>;
782
872
  }, z.core.$strict>, z.ZodObject<{
783
873
  type: z.ZodLiteral<"turn_routed">;
784
874
  turnId: z.ZodString;