@sentry/junior 0.118.0 → 0.119.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 (46) hide show
  1. package/dist/{agent-hooks-J2FB7XD6.js → agent-hooks-NZSV4QQR.js} +8 -8
  2. package/dist/api/conversations/detail.d.ts +17 -0
  3. package/dist/api/conversations/event-list.d.ts +17 -0
  4. package/dist/api/schema/conversation.d.ts +68 -0
  5. package/dist/api/schema.js +1 -1
  6. package/dist/api.js +58 -16
  7. package/dist/app.js +22 -22
  8. package/dist/{catalog-runtime-UHHLU53I.js → catalog-runtime-TAOYIZIZ.js} +5 -5
  9. package/dist/chat/slack/tools/canvas/api.d.ts +2 -9
  10. package/dist/chat/slack/tools/canvas/markdown.d.ts +9 -0
  11. package/dist/{chunk-S6R23MFB.js → chunk-4UIUDOOV.js} +12 -225
  12. package/dist/{chunk-HN6LFYG3.js → chunk-6ZR455DC.js} +2 -2
  13. package/dist/{chunk-GT2ZUALJ.js → chunk-BLQZACHV.js} +4 -4
  14. package/dist/{chunk-PJPKHGLG.js → chunk-BNJEPYTC.js} +4 -11
  15. package/dist/{chunk-KC5EE27Y.js → chunk-D3N4BPSL.js} +2 -2
  16. package/dist/{chunk-4LPPH7Y6.js → chunk-GKFDU3ZI.js} +4 -4
  17. package/dist/{chunk-FXOYURO4.js → chunk-HDFGNU5E.js} +1 -0
  18. package/dist/{chunk-HWUBBHLK.js → chunk-JLJLZS2N.js} +1 -1
  19. package/dist/{chunk-UXLYAVYL.js → chunk-JSTGI7TX.js} +1 -1
  20. package/dist/{chunk-L72GDKSN.js → chunk-JXRAOOXQ.js} +1 -1
  21. package/dist/{chunk-QWCF4RAC.js → chunk-NUENIPQL.js} +1 -1
  22. package/dist/{chunk-7SM3P4XR.js → chunk-O2ULQJWR.js} +82 -1
  23. package/dist/{chunk-7GADTCNS.js → chunk-QZ7XRJDB.js} +2 -2
  24. package/dist/{chunk-3LGCVRBQ.js → chunk-R53UT2OI.js} +1 -1
  25. package/dist/{chunk-4SOQPUF4.js → chunk-TAGV4Z3J.js} +1 -1
  26. package/dist/{chunk-6K2QE2UI.js → chunk-TGIQN7QW.js} +169 -31
  27. package/dist/{chunk-3N3FMCKN.js → chunk-VJTWKJWQ.js} +1 -1
  28. package/dist/{chunk-PWRFTDTY.js → chunk-VLTWQQKH.js} +2 -2
  29. package/dist/{chunk-3MUSSFMP.js → chunk-YLYJIQRX.js} +220 -13
  30. package/dist/{chunk-6BGUAOYP.js → chunk-ZFX4M743.js} +13 -7
  31. package/dist/{chunk-MLZFK4KP.js → chunk-ZJ6IVZVO.js} +1 -1
  32. package/dist/cli/chat.js +22 -22
  33. package/dist/cli/check.js +6 -6
  34. package/dist/cli/init.js +2 -2
  35. package/dist/cli/plugins.js +11 -11
  36. package/dist/cli/snapshot-create.js +9 -9
  37. package/dist/cli/upgrade.js +6 -6
  38. package/dist/{db-PMRHFSYL.js → db-FWGP5CKY.js} +6 -6
  39. package/dist/instrumentation.js +3 -3
  40. package/dist/nitro.js +2 -2
  41. package/dist/{oauth-callback-server-QJUC7S4X.js → oauth-callback-server-PM3QNXJQ.js} +15 -15
  42. package/dist/{runner-PZMV6JQW.js → runner-DV55N6ZB.js} +10 -10
  43. package/dist/{skills-W4JETYSV.js → skills-MANV5ZK6.js} +6 -6
  44. package/dist/{validation-IJLNHZSU.js → validation-QGB4INTI.js} +6 -6
  45. package/dist/version.js +1 -1
  46. package/package.json +5 -5
@@ -1,6 +1,3 @@
1
- import {
2
- getInterruptionMarker
3
- } from "./chunk-PJPKHGLG.js";
4
1
  import {
5
2
  SlackActionError,
6
3
  createPluginLogger,
@@ -9,29 +6,29 @@ import {
9
6
  isDmChannel,
10
7
  normalizeSlackConversationId,
11
8
  withSlackRetries
12
- } from "./chunk-GT2ZUALJ.js";
9
+ } from "./chunk-BLQZACHV.js";
13
10
  import {
14
11
  getDb,
15
12
  parseDestination
16
- } from "./chunk-KC5EE27Y.js";
13
+ } from "./chunk-D3N4BPSL.js";
17
14
  import {
18
15
  acquireActiveLock,
19
16
  getStateAdapter,
20
17
  sleep
21
- } from "./chunk-3N3FMCKN.js";
18
+ } from "./chunk-VJTWKJWQ.js";
22
19
  import {
23
20
  normalizeSlackEmojiName
24
- } from "./chunk-PWRFTDTY.js";
21
+ } from "./chunk-VLTWQQKH.js";
25
22
  import {
26
23
  pluginCatalogRuntime
27
- } from "./chunk-UXLYAVYL.js";
24
+ } from "./chunk-JSTGI7TX.js";
28
25
  import {
29
26
  fetchWithBoundedOAuthErrorBodies
30
- } from "./chunk-3LGCVRBQ.js";
27
+ } from "./chunk-R53UT2OI.js";
31
28
  import {
32
29
  logInfo,
33
30
  logWarn
34
- } from "./chunk-MLZFK4KP.js";
31
+ } from "./chunk-ZJ6IVZVO.js";
35
32
  import {
36
33
  isRecord
37
34
  } from "./chunk-OB42YVAE.js";
@@ -1714,227 +1711,12 @@ async function issuePluginCredential(input) {
1714
1711
  return parseCredentialResult(result, plugin.manifest.name);
1715
1712
  }
1716
1713
 
1717
- // src/chat/slack/output.ts
1718
- var MAX_INLINE_CHARS = 2200;
1719
- var MAX_INLINE_LINES = 45;
1720
- var CONTINUED_MARKER = "\n\n[Continued below]";
1721
- function countSlackLines(text) {
1722
- if (!text) {
1723
- return 0;
1724
- }
1725
- return text.split("\n").length;
1726
- }
1727
- function fitsInlineBudget(text, maxChars = MAX_INLINE_CHARS, maxLines = MAX_INLINE_LINES) {
1728
- return text.length <= maxChars && countSlackLines(text) <= maxLines;
1729
- }
1730
- function findSplitIndex(text, maxChars) {
1731
- if (text.length <= maxChars) {
1732
- return text.length;
1733
- }
1734
- const bounded = text.slice(0, maxChars);
1735
- const newlineIndex = bounded.lastIndexOf("\n");
1736
- if (newlineIndex > 0) {
1737
- return newlineIndex;
1738
- }
1739
- const spaceIndex = bounded.lastIndexOf(" ");
1740
- if (spaceIndex > 0) {
1741
- return spaceIndex;
1742
- }
1743
- return maxChars;
1744
- }
1745
- function splitByLineBudget(text, maxLines) {
1746
- if (maxLines <= 0) {
1747
- return "";
1748
- }
1749
- const lines = text.split("\n");
1750
- if (lines.length <= maxLines) {
1751
- return text;
1752
- }
1753
- return lines.slice(0, maxLines).join("\n");
1754
- }
1755
- function reserveInlineBudgetForSuffix(suffix, maxChars = MAX_INLINE_CHARS, maxLines = MAX_INLINE_LINES) {
1756
- return {
1757
- maxChars: Math.max(1, maxChars - suffix.length),
1758
- maxLines: Math.max(1, maxLines - Math.max(0, countSlackLines(suffix) - 1))
1759
- };
1760
- }
1761
- function forceSplitBudget(text, budget) {
1762
- const lineCount = countSlackLines(text);
1763
- return {
1764
- maxChars: text.length <= budget.maxChars ? Math.max(1, text.length - 1) : budget.maxChars,
1765
- maxLines: lineCount <= budget.maxLines ? Math.max(1, lineCount - 1) : budget.maxLines
1766
- };
1767
- }
1768
- function getFenceContinuation(text) {
1769
- let open;
1770
- for (const line of text.split("\n")) {
1771
- const trimmed = line.trimStart();
1772
- const openerMatch = trimmed.match(/^(`{3,}|~{3,})(.*)$/);
1773
- if (!openerMatch) {
1774
- continue;
1775
- }
1776
- if (!open) {
1777
- open = {
1778
- fence: openerMatch[1],
1779
- openerLine: trimmed
1780
- };
1781
- continue;
1782
- }
1783
- if (new RegExp(`^${open.fence}\\s*$`).test(trimmed)) {
1784
- open = void 0;
1785
- }
1786
- }
1787
- if (!open) {
1788
- return null;
1789
- }
1790
- return {
1791
- closeSuffix: text.endsWith("\n") ? open.fence : `
1792
- ${open.fence}`,
1793
- reopenPrefix: `${open.openerLine}
1794
- `
1795
- };
1796
- }
1797
- function appendSlackSuffix(text, marker) {
1798
- const carryover = getFenceContinuation(text);
1799
- return `${text}${carryover?.closeSuffix ?? ""}${marker}`;
1800
- }
1801
- function stripTrailingContinuationMarker(text) {
1802
- return text.endsWith(CONTINUED_MARKER) ? text.slice(0, -CONTINUED_MARKER.length) : text;
1803
- }
1804
- function takeSlackContinuationChunk(text, budget) {
1805
- let { prefix, rest } = takeSlackInlinePrefix(text, budget);
1806
- if (!rest) {
1807
- ({ prefix, rest } = takeSlackInlinePrefix(
1808
- text,
1809
- forceSplitBudget(text, budget)
1810
- ));
1811
- }
1812
- let carryover = rest ? getFenceContinuation(prefix) : null;
1813
- if (!carryover) {
1814
- return { prefix, rest };
1815
- }
1816
- const carryoverBudget = reserveInlineBudgetForSuffix(
1817
- `${carryover.closeSuffix}${CONTINUED_MARKER}`
1818
- );
1819
- ({ prefix, rest } = takeSlackInlinePrefix(text, carryoverBudget));
1820
- if (!rest) {
1821
- ({ prefix, rest } = takeSlackInlinePrefix(
1822
- text,
1823
- forceSplitBudget(text, carryoverBudget)
1824
- ));
1825
- }
1826
- carryover = rest ? getFenceContinuation(prefix) : null;
1827
- if (!carryover) {
1828
- return { prefix, rest };
1829
- }
1830
- return {
1831
- prefix,
1832
- rest: `${carryover.reopenPrefix}${rest}`
1833
- };
1834
- }
1835
- function takeSlackContinuationPrefix(text, options) {
1836
- const budget = {
1837
- maxChars: options?.maxChars ?? getSlackContinuationBudget().maxChars,
1838
- maxLines: options?.maxLines ?? getSlackContinuationBudget().maxLines
1839
- };
1840
- const { prefix, rest } = (() => {
1841
- if (options?.forceSplit) {
1842
- return takeSlackContinuationChunk(text, budget);
1843
- }
1844
- const initial = takeSlackInlinePrefix(text, budget);
1845
- return initial.rest ? takeSlackContinuationChunk(text, budget) : initial;
1846
- })();
1847
- return {
1848
- prefix,
1849
- renderedPrefix: rest ? appendSlackSuffix(prefix, CONTINUED_MARKER) : prefix,
1850
- rest
1851
- };
1852
- }
1853
- function takeSlackInlinePrefix(text, options) {
1854
- const maxChars = options?.maxChars ?? MAX_INLINE_CHARS;
1855
- const maxLines = options?.maxLines ?? MAX_INLINE_LINES;
1856
- const normalized = text.replace(/\r\n?/g, "\n");
1857
- if (!normalized) {
1858
- return { prefix: "", rest: "" };
1859
- }
1860
- if (fitsInlineBudget(normalized, maxChars, maxLines)) {
1861
- return { prefix: normalized, rest: "" };
1862
- }
1863
- const lineBounded = splitByLineBudget(normalized, maxLines);
1864
- const cutIndex = findSplitIndex(lineBounded, maxChars);
1865
- const prefix = lineBounded.slice(0, cutIndex).trimEnd();
1866
- if (prefix) {
1867
- return {
1868
- prefix,
1869
- rest: normalized.slice(prefix.length).trimStart()
1870
- };
1871
- }
1872
- const hardPrefix = normalized.slice(0, Math.max(1, maxChars)).trimEnd();
1873
- return {
1874
- prefix: hardPrefix || normalized.slice(0, Math.max(1, maxChars)),
1875
- rest: normalized.slice(hardPrefix.length || Math.max(1, maxChars)).trimStart()
1876
- };
1877
- }
1878
- function splitSlackReplyText(text, options) {
1879
- const normalized = normalizeSlackReplyMarkdown(text);
1880
- if (!normalized) {
1881
- return [];
1882
- }
1883
- const chunks = [];
1884
- const continuationBudget = reserveInlineBudgetForSuffix(CONTINUED_MARKER);
1885
- let remaining = normalized;
1886
- while (remaining) {
1887
- const fitsFinalChunk = options?.interrupted ? fitsInlineBudget(appendSlackSuffix(remaining, getInterruptionMarker())) : fitsInlineBudget(remaining);
1888
- if (fitsFinalChunk) {
1889
- chunks.push(
1890
- options?.interrupted ? appendSlackSuffix(remaining, getInterruptionMarker()) : remaining
1891
- );
1892
- break;
1893
- }
1894
- const { renderedPrefix, rest } = takeSlackContinuationPrefix(remaining, {
1895
- ...continuationBudget,
1896
- forceSplit: true
1897
- });
1898
- chunks.push(renderedPrefix);
1899
- remaining = rest;
1900
- }
1901
- if (chunks.length === 2) {
1902
- chunks[0] = stripTrailingContinuationMarker(chunks[0] ?? "");
1903
- }
1904
- return chunks;
1905
- }
1906
- function getSlackContinuationBudget() {
1907
- return reserveInlineBudgetForSuffix(CONTINUED_MARKER);
1908
- }
1909
- function buildSlackOutputMessage(text) {
1910
- const normalized = normalizeSlackReplyMarkdown(text);
1911
- if (!normalized) {
1912
- throw new Error(
1913
- `Slack output normalized to empty content: original_length=${text.length} parsed_length=${normalized.length}`
1914
- );
1915
- }
1916
- return {
1917
- markdown: normalized
1918
- };
1919
- }
1920
- var slackOutputPolicy = {
1921
- maxInlineChars: MAX_INLINE_CHARS,
1922
- maxInlineLines: MAX_INLINE_LINES
1923
- };
1924
-
1925
1714
  export {
1926
1715
  RetryableDeliveryError,
1927
1716
  actorFromRouting,
1928
1717
  assertRunRoutingConsistency,
1929
1718
  toolInvocationDestination,
1930
1719
  surfaceFromRouting,
1931
- truncateStatusText,
1932
- escapeSlackMrkdwnText,
1933
- formatSlackLink,
1934
- normalizeSlackStatusText,
1935
- splitSlackReplyText,
1936
- buildSlackOutputMessage,
1937
- slackOutputPolicy,
1938
1720
  createUserTokenStore,
1939
1721
  issueProviderCredentialLease,
1940
1722
  getSlackMessagePermalink,
@@ -1942,6 +1724,11 @@ export {
1942
1724
  uploadFilesToConversation,
1943
1725
  addReactionToMessage,
1944
1726
  removeReactionFromMessage,
1727
+ truncateStatusText,
1728
+ escapeSlackMrkdwnText,
1729
+ formatSlackLink,
1730
+ normalizeSlackReplyMarkdown,
1731
+ normalizeSlackStatusText,
1945
1732
  parseOAuthStatePayload,
1946
1733
  formatProviderLabel,
1947
1734
  resolveBaseUrl,
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-PE44LDDQ.js";
4
4
  import {
5
5
  normalizeSlackConversationId
6
- } from "./chunk-GT2ZUALJ.js";
6
+ } from "./chunk-BLQZACHV.js";
7
7
  import {
8
8
  parseSlackThreadId
9
- } from "./chunk-FXOYURO4.js";
9
+ } from "./chunk-HDFGNU5E.js";
10
10
 
11
11
  // src/handlers/health.ts
12
12
  function readHealthReport() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-KC5EE27Y.js";
3
+ } from "./chunk-D3N4BPSL.js";
4
4
  import {
5
5
  juniorConversationAnnotations
6
6
  } from "./chunk-GCGJGSQL.js";
@@ -8,14 +8,14 @@ import {
8
8
  SANDBOX_WORKSPACE_ROOT,
9
9
  getStateAdapter,
10
10
  sleep
11
- } from "./chunk-3N3FMCKN.js";
11
+ } from "./chunk-VJTWKJWQ.js";
12
12
  import {
13
13
  botConfig,
14
14
  completeObject,
15
15
  embedTexts,
16
16
  getSlackBotToken,
17
17
  standardModelId
18
- } from "./chunk-PWRFTDTY.js";
18
+ } from "./chunk-VLTWQQKH.js";
19
19
  import {
20
20
  isActorUserId,
21
21
  parseActorUserId
@@ -27,7 +27,7 @@ import {
27
27
  setSpanAttributes,
28
28
  setSpanStatus,
29
29
  withSpan
30
- } from "./chunk-MLZFK4KP.js";
30
+ } from "./chunk-ZJ6IVZVO.js";
31
31
  import {
32
32
  parseSlackChannelReferenceId,
33
33
  parseSlackMessageTs,
@@ -13,17 +13,17 @@ import {
13
13
  instructionProvenanceFor,
14
14
  sanitizePostgresJson,
15
15
  withConversationEventLock
16
- } from "./chunk-KC5EE27Y.js";
16
+ } from "./chunk-D3N4BPSL.js";
17
17
  import {
18
18
  getStateAdapter,
19
19
  sleep
20
- } from "./chunk-3N3FMCKN.js";
20
+ } from "./chunk-VJTWKJWQ.js";
21
21
  import {
22
22
  botConfig,
23
23
  escapeXml,
24
24
  resolveGatewayModel,
25
25
  unwrapCurrentInstruction
26
- } from "./chunk-PWRFTDTY.js";
26
+ } from "./chunk-VLTWQQKH.js";
27
27
  import {
28
28
  toStoredSlackActor
29
29
  } from "./chunk-HZF5P5UN.js";
@@ -32,7 +32,7 @@ import {
32
32
  logException,
33
33
  logWarn,
34
34
  setSpanAttributes
35
- } from "./chunk-MLZFK4KP.js";
35
+ } from "./chunk-ZJ6IVZVO.js";
36
36
  import {
37
37
  isRecord,
38
38
  toOptionalNumber,
@@ -2713,12 +2713,6 @@ function getChannelConfigurationServiceById(channelId) {
2713
2713
  });
2714
2714
  }
2715
2715
 
2716
- // src/chat/interruption-marker.ts
2717
- var INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
2718
- function getInterruptionMarker() {
2719
- return INTERRUPTED_MARKER;
2720
- }
2721
-
2722
2716
  // src/chat/services/pending-auth.ts
2723
2717
  var AUTH_LINK_REUSE_WINDOW_MS = 10 * 60 * 1e3;
2724
2718
  var NON_REQUEST_SKIPPED_REASON_PREFIXES = [
@@ -2840,7 +2834,6 @@ export {
2840
2834
  persistAuthPauseSessionRecord,
2841
2835
  persistContinuationSessionRecord,
2842
2836
  persistYieldSessionRecord,
2843
- getInterruptionMarker,
2844
2837
  JUNIOR_THREAD_STATE_TTL_MS,
2845
2838
  canReusePendingAuthLink,
2846
2839
  getConversationPendingAuth,
@@ -9,13 +9,13 @@ import {
9
9
  TURN_REASONING_LEVELS,
10
10
  getChatConfig,
11
11
  modelProfileSchema
12
- } from "./chunk-PWRFTDTY.js";
12
+ } from "./chunk-VLTWQQKH.js";
13
13
  import {
14
14
  juniorDestinations
15
15
  } from "./chunk-VFUK3X5B.js";
16
16
  import {
17
17
  normalizeIdentityEmail
18
- } from "./chunk-MLZFK4KP.js";
18
+ } from "./chunk-ZJ6IVZVO.js";
19
19
  import {
20
20
  parseSlackChannelReferenceId,
21
21
  parseSlackTeamId
@@ -2,18 +2,18 @@ import {
2
2
  SANDBOX_WORKSPACE_ROOT,
3
3
  getStateAdapter,
4
4
  sleep
5
- } from "./chunk-3N3FMCKN.js";
5
+ } from "./chunk-VJTWKJWQ.js";
6
6
  import {
7
7
  toOptionalTrimmed
8
- } from "./chunk-PWRFTDTY.js";
8
+ } from "./chunk-VLTWQQKH.js";
9
9
  import {
10
10
  pluginCatalogRuntime
11
- } from "./chunk-UXLYAVYL.js";
11
+ } from "./chunk-JSTGI7TX.js";
12
12
  import {
13
13
  setSpanAttributes,
14
14
  setSpanStatus,
15
15
  withSpan
16
- } from "./chunk-MLZFK4KP.js";
16
+ } from "./chunk-ZJ6IVZVO.js";
17
17
 
18
18
  // src/chat/sandbox/snapshot/profile.ts
19
19
  import { createHash } from "crypto";
@@ -289,6 +289,7 @@ function toGenAiMessagesTraceAttributes(prefix, messages) {
289
289
  return {
290
290
  [`${prefix}.message_count`]: messages.length,
291
291
  [`${prefix}.content_chars`]: contentChars,
292
+ [`${prefix}.messages.size`]: contentChars,
292
293
  ...roles.size > 0 ? { [`${prefix}.roles`]: [...roles] } : {},
293
294
  ...partTypes.size > 0 ? { [`${prefix}.part_types`]: [...partTypes] } : {}
294
295
  };
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@sentry/junior",
4
- version: "0.118.0",
4
+ version: "0.119.0",
5
5
  private: false,
6
6
  publishConfig: {
7
7
  access: "public"
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPluginCatalogRuntime
3
- } from "./chunk-3LGCVRBQ.js";
3
+ } from "./chunk-R53UT2OI.js";
4
4
 
5
5
  // src/chat/plugins/catalog-runtime.ts
6
6
  var pluginCatalogRuntime = createPluginCatalogRuntime();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getDb
3
- } from "./chunk-KC5EE27Y.js";
3
+ } from "./chunk-D3N4BPSL.js";
4
4
  import {
5
5
  juniorStats
6
6
  } from "./chunk-GCGJGSQL.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  JUNIOR_VERSION
3
- } from "./chunk-HWUBBHLK.js";
3
+ } from "./chunk-JLJLZS2N.js";
4
4
 
5
5
  // src/deployment.ts
6
6
  var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
@@ -126,9 +126,64 @@ var conversationReportToolCallSchema = z2.object({
126
126
  });
127
127
  }
128
128
  });
129
+ var conversationReportReasoningPartSchema = z2.object({
130
+ type: z2.literal("reasoning"),
131
+ text: z2.string().min(1).optional(),
132
+ redacted: z2.literal(true).optional()
133
+ }).strict().superRefine((data, context) => {
134
+ if (data.text === void 0 === (data.redacted !== true)) {
135
+ context.addIssue({
136
+ code: "custom",
137
+ message: "reasoning content must be text or explicitly redacted"
138
+ });
139
+ }
140
+ });
141
+ var conversationReportAssistantToolCallPartSchema = z2.object({
142
+ type: z2.literal("tool_call"),
143
+ toolCallId: z2.string().min(1)
144
+ }).strict();
145
+ var conversationReportAssistantMetadataSchema = z2.object({
146
+ parts: z2.array(
147
+ z2.discriminatedUnion("type", [
148
+ conversationReportReasoningPartSchema,
149
+ conversationReportAssistantToolCallPartSchema
150
+ ])
151
+ ).min(1)
152
+ }).strict();
129
153
  var conversationReportToolCallsEventDataSchema = z2.object({
130
154
  type: z2.literal("tool_calls"),
131
- calls: z2.array(conversationReportToolCallSchema).min(1)
155
+ calls: z2.array(conversationReportToolCallSchema).min(1),
156
+ assistant: conversationReportAssistantMetadataSchema.optional()
157
+ }).strict().superRefine((data, context) => {
158
+ if (!data.assistant) return;
159
+ const callCounts = /* @__PURE__ */ new Map();
160
+ for (const call of data.calls) {
161
+ callCounts.set(
162
+ call.toolCallId,
163
+ (callCounts.get(call.toolCallId) ?? 0) + 1
164
+ );
165
+ }
166
+ const partCounts = /* @__PURE__ */ new Map();
167
+ for (const part of data.assistant.parts) {
168
+ if (part.type !== "tool_call") continue;
169
+ partCounts.set(
170
+ part.toolCallId,
171
+ (partCounts.get(part.toolCallId) ?? 0) + 1
172
+ );
173
+ }
174
+ if (callCounts.size !== partCounts.size || [...callCounts].some(
175
+ ([toolCallId, count]) => partCounts.get(toolCallId) !== count
176
+ )) {
177
+ context.addIssue({
178
+ code: "custom",
179
+ path: ["assistant", "parts"],
180
+ message: "assistant tool parts must reference every call exactly once"
181
+ });
182
+ }
183
+ });
184
+ var conversationReportAssistantMessageEventDataSchema = z2.object({
185
+ type: z2.literal("assistant_message"),
186
+ parts: z2.array(conversationReportReasoningPartSchema).min(1)
132
187
  }).strict();
133
188
  var conversationReportTurnLifecycleEventDataSchema = z2.discriminatedUnion(
134
189
  "state",
@@ -199,6 +254,7 @@ var conversationReportSubagentEventDataSchema = z2.object({
199
254
  var conversationReportEventDataSchema = z2.discriminatedUnion("type", [
200
255
  conversationReportMessageEventDataSchema,
201
256
  conversationReportMessageHandledEventDataSchema,
257
+ conversationReportAssistantMessageEventDataSchema,
202
258
  conversationReportToolCallsEventDataSchema,
203
259
  conversationReportTurnLifecycleEventDataSchema,
204
260
  conversationReportTurnContextEventDataSchema,
@@ -270,6 +326,31 @@ function validateConversationEvents(report, context) {
270
326
  message: "redacted event history must redact tool payloads"
271
327
  });
272
328
  }
329
+ if (report.eventHistory.status === "redacted" && event.data.type === "assistant_message" && event.data.parts.some((part) => part.text !== void 0)) {
330
+ context.addIssue({
331
+ code: "custom",
332
+ path: ["events", index, "data"],
333
+ message: "redacted event history must redact assistant messages"
334
+ });
335
+ }
336
+ if (report.eventHistory.status === "available" && event.data.type === "assistant_message" && event.data.parts.some((part) => part.redacted === true)) {
337
+ context.addIssue({
338
+ code: "custom",
339
+ path: ["events", index, "data"],
340
+ message: "available event history must expose reasoning"
341
+ });
342
+ }
343
+ if (event.data.type === "tool_calls" && (report.eventHistory.status === "redacted" && event.data.assistant?.parts.some(
344
+ (part) => part.type === "reasoning" && part.text !== void 0
345
+ ) || report.eventHistory.status === "available" && event.data.assistant?.parts.some(
346
+ (part) => part.type === "reasoning" && part.redacted === true
347
+ ))) {
348
+ context.addIssue({
349
+ code: "custom",
350
+ path: ["events", index, "data", "assistant"],
351
+ message: "assistant reasoning must match event history visibility"
352
+ });
353
+ }
273
354
  }
274
355
  }
275
356
  var conversationDetailReportSchema = conversationSummaryReportSchema.extend({
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-UXLYAVYL.js";
3
+ } from "./chunk-JSTGI7TX.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-MLZFK4KP.js";
6
+ } from "./chunk-ZJ6IVZVO.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-3V7OFJZC.js";
@@ -5,7 +5,7 @@ import {
5
5
  logInfo,
6
6
  logWarn,
7
7
  setSpanAttributes
8
- } from "./chunk-MLZFK4KP.js";
8
+ } from "./chunk-ZJ6IVZVO.js";
9
9
  import {
10
10
  discoverInstalledPluginPackageContent,
11
11
  normalizePluginPackageNames
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-UXLYAVYL.js";
3
+ } from "./chunk-JSTGI7TX.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";