@sentry/junior 0.71.2 → 0.72.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 (57) hide show
  1. package/bin/junior.mjs +10 -0
  2. package/dist/api-reference.d.ts +2 -0
  3. package/dist/app.d.ts +5 -5
  4. package/dist/app.js +1039 -1971
  5. package/dist/chat/agent-dispatch/heartbeat.d.ts +0 -6
  6. package/dist/chat/mcp/errors.d.ts +3 -0
  7. package/dist/chat/mcp/tool-manager.d.ts +5 -1
  8. package/dist/chat/plugins/agent-hooks.d.ts +3 -2
  9. package/dist/chat/requester.d.ts +60 -0
  10. package/dist/chat/respond.d.ts +2 -6
  11. package/dist/chat/runtime/agent-continue-runner.d.ts +25 -0
  12. package/dist/chat/runtime/reply-executor.d.ts +4 -4
  13. package/dist/chat/runtime/turn.d.ts +2 -2
  14. package/dist/chat/services/agent-continue.d.ts +27 -0
  15. package/dist/chat/services/message-actor-identity.d.ts +12 -4
  16. package/dist/chat/services/turn-session-record.d.ts +10 -7
  17. package/dist/chat/slack/user.d.ts +4 -4
  18. package/dist/chat/state/adapter.d.ts +2 -0
  19. package/dist/chat/state/conversation-details.d.ts +4 -3
  20. package/dist/chat/state/session-log.d.ts +43 -0
  21. package/dist/chat/state/turn-session.d.ts +7 -10
  22. package/dist/chat/task-execution/queue.d.ts +1 -1
  23. package/dist/chat/task-execution/slack-work.d.ts +5 -5
  24. package/dist/chat/task-execution/store.d.ts +83 -48
  25. package/dist/chat/task-execution/worker.d.ts +3 -3
  26. package/dist/chat/tools/definition.d.ts +3 -0
  27. package/dist/chat/tools/execution/tool-error-handler.d.ts +2 -1
  28. package/dist/chat/tools/types.d.ts +2 -5
  29. package/dist/{chunk-R62YWUNO.js → chunk-3FYPXHPL.js} +10 -28
  30. package/dist/chunk-4JXCSGSA.js +212 -0
  31. package/dist/{chunk-GT67ZWZQ.js → chunk-55XEZFGD.js} +5 -3
  32. package/dist/{chunk-BBXYXOJW.js → chunk-6GEYPE6T.js} +18 -523
  33. package/dist/chunk-G3E7SCME.js +28 -0
  34. package/dist/{chunk-UXG6TU2U.js → chunk-GB3AL54K.js} +8 -93
  35. package/dist/chunk-HNMUVGSR.js +1119 -0
  36. package/dist/{chunk-XE2VFQQN.js → chunk-ICKIDP7G.js} +1 -1
  37. package/dist/chunk-KVZL5NZS.js +519 -0
  38. package/dist/chunk-PP7AGSBU.js +185 -0
  39. package/dist/{chunk-B5HKWWQB.js → chunk-VLIO6RQR.js} +8 -6
  40. package/dist/{chunk-HOGQL2H6.js → chunk-VSNA5KAB.js} +177 -101
  41. package/dist/{chunk-76YMBKW7.js → chunk-XC33FJZN.js} +4 -12
  42. package/dist/{chunk-JS4HURDT.js → chunk-ZJQPA67D.js} +25 -25
  43. package/dist/cli/check.js +10 -8
  44. package/dist/cli/run.js +9 -1
  45. package/dist/cli/snapshot-warmup.js +10 -7
  46. package/dist/cli/upgrade.js +599 -0
  47. package/dist/nitro.d.ts +1 -1
  48. package/dist/nitro.js +5 -4
  49. package/dist/plugins.d.ts +1 -1
  50. package/dist/reporting/conversations.d.ts +116 -0
  51. package/dist/reporting.d.ts +24 -129
  52. package/dist/reporting.js +310 -158
  53. package/package.json +3 -3
  54. package/dist/chat/runtime/timeout-resume-runner.d.ts +0 -19
  55. package/dist/chat/services/requester-identity.d.ts +0 -19
  56. package/dist/chat/services/timeout-resume.d.ts +0 -23
  57. package/dist/handlers/turn-resume.d.ts +0 -4
@@ -1,17 +1,19 @@
1
1
  import {
2
- SANDBOX_WORKSPACE_ROOT,
3
- getStateAdapter
4
- } from "./chunk-R62YWUNO.js";
2
+ SANDBOX_WORKSPACE_ROOT
3
+ } from "./chunk-G3E7SCME.js";
5
4
  import {
6
5
  getPluginRuntimeDependencies,
7
6
  getPluginRuntimePostinstall
8
- } from "./chunk-UXG6TU2U.js";
7
+ } from "./chunk-GB3AL54K.js";
8
+ import {
9
+ getStateAdapter
10
+ } from "./chunk-3FYPXHPL.js";
9
11
  import {
10
12
  toOptionalTrimmed
11
- } from "./chunk-JS4HURDT.js";
13
+ } from "./chunk-ZJQPA67D.js";
12
14
  import {
13
15
  withSpan
14
- } from "./chunk-BBXYXOJW.js";
16
+ } from "./chunk-6GEYPE6T.js";
15
17
 
16
18
  // src/chat/sandbox/runtime-dependency-snapshots.ts
17
19
  import { createHash } from "crypto";
@@ -1,37 +1,46 @@
1
1
  import {
2
- SANDBOX_DATA_ROOT,
3
- SANDBOX_WORKSPACE_ROOT,
4
- getConnectedStateContext,
5
- getStateAdapter,
6
- sandboxSkillDir
7
- } from "./chunk-R62YWUNO.js";
8
- import {
9
- isActorUserId,
10
- parseActorUserId
11
- } from "./chunk-UXG6TU2U.js";
2
+ recordConversationActivity
3
+ } from "./chunk-HNMUVGSR.js";
12
4
  import {
13
5
  isConversationChannel,
14
6
  isConversationScopedChannel,
15
7
  isDmChannel,
16
8
  normalizeSlackConversationId,
17
9
  parseDestination
18
- } from "./chunk-76YMBKW7.js";
10
+ } from "./chunk-XC33FJZN.js";
11
+ import {
12
+ SANDBOX_DATA_ROOT,
13
+ SANDBOX_WORKSPACE_ROOT,
14
+ sandboxSkillDir
15
+ } from "./chunk-G3E7SCME.js";
16
+ import {
17
+ listReferenceFiles,
18
+ soulPathCandidates,
19
+ worldPathCandidates
20
+ } from "./chunk-KVZL5NZS.js";
21
+ import {
22
+ getConnectedStateContext,
23
+ getStateAdapter
24
+ } from "./chunk-3FYPXHPL.js";
19
25
  import {
20
26
  TURN_CONTEXT_TAG,
21
27
  botConfig,
22
28
  getChatConfig,
23
29
  parseSlackThreadId
24
- } from "./chunk-JS4HURDT.js";
30
+ } from "./chunk-ZJQPA67D.js";
31
+ import {
32
+ isActorUserId,
33
+ parseActorUserId,
34
+ parseStoredSlackRequester,
35
+ storedSlackRequesterSchema
36
+ } from "./chunk-PP7AGSBU.js";
25
37
  import {
26
38
  isRecord,
27
- listReferenceFiles,
28
39
  logException,
29
40
  logInfo,
30
41
  logWarn,
31
- soulPathCandidates,
32
- toOptionalNumber,
33
- worldPathCandidates
34
- } from "./chunk-BBXYXOJW.js";
42
+ toOptionalNumber
43
+ } from "./chunk-6GEYPE6T.js";
35
44
  import {
36
45
  sentry_exports
37
46
  } from "./chunk-Z3YD6NHK.js";
@@ -818,6 +827,11 @@ function GET() {
818
827
  });
819
828
  }
820
829
 
830
+ // src/chat/xml.ts
831
+ function escapeXml(value) {
832
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
833
+ }
834
+
821
835
  // src/chat/prompt.ts
822
836
  import fs from "fs";
823
837
  import path from "path";
@@ -1243,11 +1257,6 @@ var slackOutputPolicy = {
1243
1257
  maxInlineLines: MAX_INLINE_LINES
1244
1258
  };
1245
1259
 
1246
- // src/chat/xml.ts
1247
- function escapeXml(value) {
1248
- return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
1249
- }
1250
-
1251
1260
  // src/chat/prompt.ts
1252
1261
  var DEFAULT_SOUL = "You are Junior, a practical and concise assistant.";
1253
1262
  function getLoggedMarkdownFiles() {
@@ -1704,9 +1713,6 @@ function buildTurnContextPrompt(params) {
1704
1713
  return sections.join("\n\n");
1705
1714
  }
1706
1715
 
1707
- // src/chat/state/turn-session.ts
1708
- import { THREAD_STATE_TTL_MS } from "chat";
1709
-
1710
1716
  // src/chat/state/session-log.ts
1711
1717
  import { isDeepStrictEqual } from "util";
1712
1718
  import { z } from "zod";
@@ -1721,13 +1727,21 @@ var piMessageEntrySchema = z.object({
1721
1727
  schemaVersion: z.literal(AGENT_SESSION_LOG_SCHEMA_VERSION),
1722
1728
  type: z.literal("pi_message"),
1723
1729
  sessionId: z.string().min(1).default(INITIAL_SESSION_ID),
1724
- message: piMessageSchema
1730
+ message: piMessageSchema,
1731
+ requester: storedSlackRequesterSchema.optional()
1725
1732
  });
1726
1733
  var projectionResetEntrySchema = z.object({
1727
1734
  schemaVersion: z.literal(AGENT_SESSION_LOG_SCHEMA_VERSION),
1728
1735
  type: z.literal("projection_reset"),
1729
1736
  sessionId: z.string().min(1).default(INITIAL_SESSION_ID),
1730
- messages: z.array(piMessageSchema)
1737
+ messages: z.array(piMessageSchema),
1738
+ requester: storedSlackRequesterSchema.optional()
1739
+ });
1740
+ var requesterRecordedEntrySchema = z.object({
1741
+ schemaVersion: z.literal(AGENT_SESSION_LOG_SCHEMA_VERSION),
1742
+ type: z.literal("requester_recorded"),
1743
+ sessionId: z.string().min(1).default(INITIAL_SESSION_ID),
1744
+ requester: storedSlackRequesterSchema
1731
1745
  });
1732
1746
  var mcpProviderConnectedEntrySchema = z.object({
1733
1747
  schemaVersion: z.literal(AGENT_SESSION_LOG_SCHEMA_VERSION),
@@ -1766,6 +1780,7 @@ var authorizationCompletedEntrySchema = z.object({
1766
1780
  var sessionLogEntrySchema = z.discriminatedUnion("type", [
1767
1781
  piMessageEntrySchema,
1768
1782
  projectionResetEntrySchema,
1783
+ requesterRecordedEntrySchema,
1769
1784
  mcpProviderConnectedEntrySchema,
1770
1785
  authorizationRequestedEntrySchema,
1771
1786
  authorizationCompletedEntrySchema
@@ -1842,20 +1857,36 @@ function projectionEntries(entries, sessionId) {
1842
1857
  const currentId = resetIndex < 0 ? INITIAL_SESSION_ID : entrySessionId(entries[resetIndex]);
1843
1858
  return entries.slice(startIndex).filter((entry) => entrySessionId(entry) === currentId);
1844
1859
  }
1845
- function piEntry(message, sessionId) {
1860
+ function findLastIndex(values, predicate) {
1861
+ for (let index = values.length - 1; index >= 0; index -= 1) {
1862
+ if (predicate(values[index])) return index;
1863
+ }
1864
+ return -1;
1865
+ }
1866
+ function piEntry(message, sessionId, requester) {
1846
1867
  return {
1847
1868
  schemaVersion: AGENT_SESSION_LOG_SCHEMA_VERSION,
1848
1869
  type: "pi_message",
1849
1870
  sessionId,
1850
- message
1871
+ message,
1872
+ ...requester ? { requester } : {}
1851
1873
  };
1852
1874
  }
1853
- function resetEntry(messages, sessionId) {
1875
+ function resetEntry(messages, sessionId, requester) {
1854
1876
  return {
1855
1877
  schemaVersion: AGENT_SESSION_LOG_SCHEMA_VERSION,
1856
1878
  type: "projection_reset",
1857
1879
  sessionId,
1858
- messages
1880
+ messages,
1881
+ ...requester ? { requester } : {}
1882
+ };
1883
+ }
1884
+ function requesterRecordedEntry(requester, sessionId) {
1885
+ return {
1886
+ schemaVersion: AGENT_SESSION_LOG_SCHEMA_VERSION,
1887
+ type: "requester_recorded",
1888
+ sessionId,
1889
+ requester
1859
1890
  };
1860
1891
  }
1861
1892
  function mcpProviderConnectedEntry(provider, sessionId) {
@@ -1916,9 +1947,17 @@ function decode(value) {
1916
1947
  }
1917
1948
  function project(entries, sessionId) {
1918
1949
  let messages = [];
1950
+ let requester;
1919
1951
  for (const entry of projectionEntries(entries, sessionId)) {
1920
1952
  if (entry.type === "pi_message") {
1921
1953
  messages.push(entry.message);
1954
+ if (entry.message.role === "user" && entry.requester) {
1955
+ requester = entry.requester;
1956
+ }
1957
+ continue;
1958
+ }
1959
+ if (entry.type === "requester_recorded") {
1960
+ requester = entry.requester;
1922
1961
  continue;
1923
1962
  }
1924
1963
  if (entry.type === "authorization_completed") {
@@ -1929,8 +1968,14 @@ function project(entries, sessionId) {
1929
1968
  continue;
1930
1969
  }
1931
1970
  messages = [...entry.messages];
1971
+ if (entry.requester) {
1972
+ requester = entry.requester;
1973
+ }
1932
1974
  }
1933
- return messages;
1975
+ return { messages, requester };
1976
+ }
1977
+ function projectMessages(entries, sessionId) {
1978
+ return project(entries, sessionId).messages;
1934
1979
  }
1935
1980
  function connectedMcpProviders(entries, sessionId) {
1936
1981
  const providers = /* @__PURE__ */ new Set();
@@ -1941,12 +1986,29 @@ function connectedMcpProviders(entries, sessionId) {
1941
1986
  }
1942
1987
  return [...providers].sort((left, right) => left.localeCompare(right));
1943
1988
  }
1944
- function commitEntries(existingMessages, nextMessages, sessionId, entries) {
1989
+ function commitEntries(existingMessages, nextMessages, sessionId, entries, existingRequester, requester) {
1945
1990
  const matchingPrefix = countMatchingPrefix(existingMessages, nextMessages);
1946
1991
  if (matchingPrefix === existingMessages.length) {
1947
- return nextMessages.slice(matchingPrefix).map((message) => piEntry(message, sessionId));
1992
+ const newMessages = nextMessages.slice(matchingPrefix);
1993
+ if (newMessages.length === 0 && requester && !isDeepStrictEqual(existingRequester, requester)) {
1994
+ return [requesterRecordedEntry(requester, sessionId)];
1995
+ }
1996
+ const requesterIndex = requester ? findLastIndex(newMessages, (m) => m.role === "user") : -1;
1997
+ return newMessages.map(
1998
+ (message, index) => piEntry(
1999
+ message,
2000
+ sessionId,
2001
+ index === requesterIndex ? requester : void 0
2002
+ )
2003
+ );
1948
2004
  }
1949
- return [resetEntry(nextMessages, nextSessionId(entries))];
2005
+ return [
2006
+ resetEntry(
2007
+ nextMessages,
2008
+ nextSessionId(entries),
2009
+ requester ?? existingRequester
2010
+ )
2011
+ ];
1950
2012
  }
1951
2013
  function redisStore(redisStateAdapter) {
1952
2014
  const client = redisStateAdapter.getClient();
@@ -2002,12 +2064,12 @@ async function loadMessages(args) {
2002
2064
  return [];
2003
2065
  }
2004
2066
  const store = args.store ?? await defaultStore();
2005
- const messages = project(await store.read(args), args.sessionId);
2067
+ const messages = projectMessages(await store.read(args), args.sessionId);
2006
2068
  return messages.length >= messageCount ? messages.slice(0, messageCount) : void 0;
2007
2069
  }
2008
2070
  async function loadProjection(args) {
2009
2071
  const store = args.store ?? await defaultStore();
2010
- return project(await store.read(args), args.sessionId);
2072
+ return project(await store.read(args), args.sessionId).messages;
2011
2073
  }
2012
2074
  async function loadConnectedMcpProviders(args) {
2013
2075
  return connectedMcpProviders(await loadEntries(args));
@@ -2077,13 +2139,15 @@ async function recordAuthorizationCompleted(args) {
2077
2139
  async function commitMessages(args) {
2078
2140
  const store = args.store ?? await defaultStore();
2079
2141
  const entries = await store.read(args);
2080
- const existingMessages = project(entries);
2142
+ const existingProjection = project(entries);
2081
2143
  const currentId = currentSessionId(entries);
2082
2144
  const nextEntries = commitEntries(
2083
- existingMessages,
2145
+ existingProjection.messages,
2084
2146
  args.messages,
2085
2147
  currentId,
2086
- entries
2148
+ entries,
2149
+ existingProjection.requester,
2150
+ args.requester
2087
2151
  );
2088
2152
  await store.append({
2089
2153
  scope: args,
@@ -2096,6 +2160,7 @@ async function commitMessages(args) {
2096
2160
  }
2097
2161
 
2098
2162
  // src/chat/state/turn-session.ts
2163
+ import { THREAD_STATE_TTL_MS } from "chat";
2099
2164
  var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session";
2100
2165
  var AGENT_TURN_SESSION_INDEX_KEY = `${AGENT_TURN_SESSION_PREFIX}:index`;
2101
2166
  var AGENT_TURN_SESSION_INDEX_MAX_LENGTH = 5e3;
@@ -2109,6 +2174,9 @@ function agentTurnSessionConversationIndexKey(conversationId) {
2109
2174
  function toFiniteNonNegativeNumber(value) {
2110
2175
  return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : void 0;
2111
2176
  }
2177
+ function toNonNegativeInteger(value) {
2178
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
2179
+ }
2112
2180
  function parseAgentTurnUsage(value) {
2113
2181
  if (!isRecord(value)) {
2114
2182
  return void 0;
@@ -2128,23 +2196,6 @@ function parseAgentTurnUsage(value) {
2128
2196
  }
2129
2197
  return Object.keys(usage).length > 0 ? usage : void 0;
2130
2198
  }
2131
- function parseAgentTurnRequester(value) {
2132
- if (!isRecord(value)) {
2133
- return void 0;
2134
- }
2135
- const requester = {};
2136
- for (const field of [
2137
- "email",
2138
- "fullName",
2139
- "slackUserId",
2140
- "slackUserName"
2141
- ]) {
2142
- if (typeof value[field] === "string" && value[field].trim()) {
2143
- requester[field] = value[field].trim();
2144
- }
2145
- }
2146
- return Object.keys(requester).length > 0 ? requester : void 0;
2147
- }
2148
2199
  function parseStoredRecord(value) {
2149
2200
  if (isRecord(value)) {
2150
2201
  return value;
@@ -2184,9 +2235,12 @@ function parseAgentTurnSessionFields(parsed) {
2184
2235
  const cumulativeUsage = parseAgentTurnUsage(parsed.cumulativeUsage);
2185
2236
  const lastProgressAtMs = toFiniteNonNegativeNumber(parsed.lastProgressAtMs);
2186
2237
  const logSessionId = typeof parsed.logSessionId === "string" ? parsed.logSessionId : void 0;
2187
- const requester = parseAgentTurnRequester(parsed.requester);
2238
+ const requester = parseStoredSlackRequester(parsed.requester);
2188
2239
  const startedAtMs = toFiniteNonNegativeNumber(parsed.startedAtMs);
2189
2240
  const surface = parseAgentTurnSurface(parsed.surface);
2241
+ const turnStartMessageIndex = toNonNegativeInteger(
2242
+ parsed.turnStartMessageIndex
2243
+ );
2190
2244
  const destination = parsed.destination === void 0 ? void 0 : parseDestination(parsed.destination);
2191
2245
  if (typeof conversationId !== "string" || typeof sessionId !== "string" || sliceId === void 0 || version === void 0 || updatedAtMs === void 0 || parsed.destination !== void 0 && !destination) {
2192
2246
  return void 0;
@@ -2215,6 +2269,7 @@ function parseAgentTurnSessionFields(parsed) {
2215
2269
  ...typeof parsed.errorMessage === "string" ? { errorMessage: parsed.errorMessage } : {},
2216
2270
  ...typeof parsed.resumedFromSliceId === "number" ? { resumedFromSliceId: parsed.resumedFromSliceId } : {},
2217
2271
  ...surface ? { surface } : {},
2272
+ ...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {},
2218
2273
  ...typeof parsed.traceId === "string" ? { traceId: parsed.traceId } : {}
2219
2274
  };
2220
2275
  }
@@ -2247,6 +2302,7 @@ function parseAgentTurnSessionSummary(value) {
2247
2302
  const {
2248
2303
  errorMessage: _errorMessage,
2249
2304
  logSessionId: _logSessionId,
2305
+ turnStartMessageIndex: _turnStartMessageIndex,
2250
2306
  ...summary
2251
2307
  } = parsed;
2252
2308
  return summary;
@@ -2265,6 +2321,27 @@ async function appendAgentTurnSessionSummary(summary, ttlMs) {
2265
2321
  )
2266
2322
  ]);
2267
2323
  }
2324
+ async function recordConversationActivityBestEffort(args) {
2325
+ try {
2326
+ await recordConversationActivity({
2327
+ activityAtMs: args.summary.updatedAtMs,
2328
+ channelName: args.summary.channelName,
2329
+ conversationId: args.summary.conversationId,
2330
+ destination: args.summary.destination,
2331
+ nowMs: args.nowMs,
2332
+ requester: args.summary.requester,
2333
+ source: args.summary.surface
2334
+ });
2335
+ } catch (error) {
2336
+ logException(
2337
+ error,
2338
+ "conversation_activity_record_failed",
2339
+ { conversationId: args.summary.conversationId },
2340
+ {},
2341
+ "Failed to mirror turn session summary into conversation activity"
2342
+ );
2343
+ }
2344
+ }
2268
2345
  function materializePiMessages(committedMessageCount, includeProjectionTail, sessionMessages, sessionProjection) {
2269
2346
  if (committedMessageCount === 0) {
2270
2347
  return sessionProjection;
@@ -2301,7 +2378,8 @@ function materializeAgentTurnSessionRecord(stored, piMessages) {
2301
2378
  ...stored.requester ? { requester: stored.requester } : {},
2302
2379
  ...stored.resumedFromSliceId !== void 0 ? { resumedFromSliceId: stored.resumedFromSliceId } : {},
2303
2380
  ...stored.surface ? { surface: stored.surface } : {},
2304
- ...stored.traceId ? { traceId: stored.traceId } : {}
2381
+ ...stored.traceId ? { traceId: stored.traceId } : {},
2382
+ ...stored.turnStartMessageIndex !== void 0 ? { turnStartMessageIndex: stored.turnStartMessageIndex } : {}
2305
2383
  };
2306
2384
  }
2307
2385
  async function getStoredAgentTurnSessionRecord(conversationId, sessionId) {
@@ -2367,7 +2445,8 @@ function buildStoredRecord(args) {
2367
2445
  ...args.errorMessage ? { errorMessage: args.errorMessage } : {},
2368
2446
  ...typeof args.resumedFromSliceId === "number" ? { resumedFromSliceId: args.resumedFromSliceId } : {},
2369
2447
  ...args.surface ? { surface: args.surface } : {},
2370
- ...args.traceId ? { traceId: args.traceId } : {}
2448
+ ...args.traceId ? { traceId: args.traceId } : {},
2449
+ ...args.turnStartMessageIndex !== void 0 ? { turnStartMessageIndex: args.turnStartMessageIndex } : {}
2371
2450
  };
2372
2451
  }
2373
2452
  async function setStoredRecord(args) {
@@ -2382,6 +2461,7 @@ async function setStoredRecord(args) {
2382
2461
  committedMessageCount: _committedMessageCount,
2383
2462
  errorMessage: _errorMessage,
2384
2463
  logSessionId: _logSessionId,
2464
+ turnStartMessageIndex: _turnStartMessageIndex,
2385
2465
  ...summary
2386
2466
  } = args.record;
2387
2467
  await appendAgentTurnSessionSummary(summary, args.ttlMs);
@@ -2418,6 +2498,7 @@ async function updateAgentTurnSessionState(args) {
2418
2498
  ...args.existing.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.existing.resumedFromSliceId } : {},
2419
2499
  ...args.existing.surface ? { surface: args.existing.surface } : {},
2420
2500
  ...args.existing.traceId ? { traceId: args.existing.traceId } : {},
2501
+ ...args.existing.turnStartMessageIndex !== void 0 ? { turnStartMessageIndex: args.existing.turnStartMessageIndex } : {},
2421
2502
  ...args.errorMessage ?? args.existing.errorMessage ? { errorMessage: args.errorMessage ?? args.existing.errorMessage } : {}
2422
2503
  })
2423
2504
  });
@@ -2431,6 +2512,7 @@ async function upsertAgentTurnSessionRecord(args) {
2431
2512
  const commit = await commitMessages({
2432
2513
  conversationId: args.conversationId,
2433
2514
  messages: args.piMessages,
2515
+ requester: args.requester ?? existingRecord?.requester,
2434
2516
  ttlMs
2435
2517
  });
2436
2518
  return await setStoredRecord({
@@ -2456,7 +2538,10 @@ async function upsertAgentTurnSessionRecord(args) {
2456
2538
  ...args.errorMessage ? { errorMessage: args.errorMessage } : {},
2457
2539
  ...args.resumedFromSliceId !== void 0 ? { resumedFromSliceId: args.resumedFromSliceId } : {},
2458
2540
  ...args.surface ?? existingRecord?.surface ? { surface: args.surface ?? existingRecord?.surface } : {},
2459
- ...args.traceId ?? existingRecord?.traceId ? { traceId: args.traceId ?? existingRecord?.traceId } : {}
2541
+ ...args.traceId ?? existingRecord?.traceId ? { traceId: args.traceId ?? existingRecord?.traceId } : {},
2542
+ ...(args.turnStartMessageIndex ?? existingRecord?.turnStartMessageIndex) !== void 0 ? {
2543
+ turnStartMessageIndex: args.turnStartMessageIndex ?? existingRecord?.turnStartMessageIndex
2544
+ } : {}
2460
2545
  })
2461
2546
  });
2462
2547
  }
@@ -2467,32 +2552,34 @@ async function recordAgentTurnSessionSummary(args) {
2467
2552
  );
2468
2553
  const nowMs = Date.now();
2469
2554
  const ttlMs = Math.max(1, args.ttlMs ?? AGENT_TURN_SESSION_TTL_MS);
2470
- await appendAgentTurnSessionSummary(
2471
- {
2472
- version: existing?.version ?? 0,
2473
- ...args.channelName ?? existing?.channelName ? { channelName: args.channelName ?? existing?.channelName } : {},
2474
- conversationId: args.conversationId,
2475
- sessionId: args.sessionId,
2476
- sliceId: args.sliceId,
2477
- startedAtMs: existing?.startedAtMs ?? args.startedAtMs ?? nowMs,
2478
- lastProgressAtMs: args.lastProgressAtMs ?? nowMs,
2479
- state: args.state,
2480
- updatedAtMs: nowMs,
2481
- cumulativeDurationMs: toFiniteNonNegativeNumber(args.cumulativeDurationMs) ?? existing?.cumulativeDurationMs ?? 0,
2482
- ...args.cumulativeUsage ?? existing?.cumulativeUsage ? { cumulativeUsage: args.cumulativeUsage ?? existing?.cumulativeUsage } : {},
2483
- ...args.destination ?? existing?.destination ? { destination: args.destination ?? existing?.destination } : {},
2484
- ...args.requester ?? existing?.requester ? { requester: args.requester ?? existing?.requester } : {},
2485
- ...Array.isArray(args.loadedSkillNames) ? {
2486
- loadedSkillNames: args.loadedSkillNames.filter(
2487
- (value) => typeof value === "string"
2488
- )
2489
- } : existing?.loadedSkillNames ? { loadedSkillNames: existing.loadedSkillNames } : {},
2490
- ...args.resumeReason ? { resumeReason: args.resumeReason } : {},
2491
- ...args.surface ?? existing?.surface ? { surface: args.surface ?? existing?.surface } : {},
2492
- ...args.traceId ?? existing?.traceId ? { traceId: args.traceId ?? existing?.traceId } : {}
2493
- },
2494
- ttlMs
2495
- );
2555
+ const summary = {
2556
+ version: existing?.version ?? 0,
2557
+ ...args.channelName ?? existing?.channelName ? { channelName: args.channelName ?? existing?.channelName } : {},
2558
+ conversationId: args.conversationId,
2559
+ sessionId: args.sessionId,
2560
+ sliceId: args.sliceId,
2561
+ startedAtMs: existing?.startedAtMs ?? args.startedAtMs ?? nowMs,
2562
+ lastProgressAtMs: args.lastProgressAtMs ?? nowMs,
2563
+ state: args.state,
2564
+ updatedAtMs: nowMs,
2565
+ cumulativeDurationMs: toFiniteNonNegativeNumber(args.cumulativeDurationMs) ?? existing?.cumulativeDurationMs ?? 0,
2566
+ ...args.cumulativeUsage ?? existing?.cumulativeUsage ? { cumulativeUsage: args.cumulativeUsage ?? existing?.cumulativeUsage } : {},
2567
+ ...args.destination ?? existing?.destination ? { destination: args.destination ?? existing?.destination } : {},
2568
+ ...args.requester ?? existing?.requester ? { requester: args.requester ?? existing?.requester } : {},
2569
+ ...Array.isArray(args.loadedSkillNames) ? {
2570
+ loadedSkillNames: args.loadedSkillNames.filter(
2571
+ (value) => typeof value === "string"
2572
+ )
2573
+ } : existing?.loadedSkillNames ? { loadedSkillNames: existing.loadedSkillNames } : {},
2574
+ ...args.resumeReason ? { resumeReason: args.resumeReason } : {},
2575
+ ...args.surface ?? existing?.surface ? { surface: args.surface ?? existing?.surface } : {},
2576
+ ...args.traceId ?? existing?.traceId ? { traceId: args.traceId ?? existing?.traceId } : {}
2577
+ };
2578
+ await appendAgentTurnSessionSummary(summary, ttlMs);
2579
+ await recordConversationActivityBestEffort({
2580
+ nowMs,
2581
+ summary
2582
+ });
2496
2583
  }
2497
2584
  async function readAgentTurnSessionSummariesFromIndex(key2) {
2498
2585
  const stateAdapter = getStateAdapter();
@@ -2513,9 +2600,6 @@ async function readAgentTurnSessionSummariesFromIndex(key2) {
2513
2600
  (left, right) => right.updatedAtMs - left.updatedAtMs
2514
2601
  );
2515
2602
  }
2516
- async function listAgentTurnSessionSummaries(limit = 50) {
2517
- return (await readAgentTurnSessionSummariesFromIndex(AGENT_TURN_SESSION_INDEX_KEY)).slice(0, Math.max(0, Math.floor(limit)));
2518
- }
2519
2603
  async function listAgentTurnSessionSummariesForConversation(conversationId) {
2520
2604
  const summaries = await readAgentTurnSessionSummariesFromIndex(
2521
2605
  agentTurnSessionConversationIndexKey(conversationId)
@@ -2687,15 +2771,8 @@ function conversationContextKey(conversationId) {
2687
2771
  function conversationTitleKey(conversationId) {
2688
2772
  return `${CONVERSATION_PREFIX}:${conversationId}:title`;
2689
2773
  }
2690
- function parseAgentTurnRequester2(value) {
2691
- if (!isRecord(value)) return void 0;
2692
- const requester = {
2693
- ...typeof value.email === "string" ? { email: value.email } : {},
2694
- ...typeof value.fullName === "string" ? { fullName: value.fullName } : {},
2695
- ...typeof value.slackUserId === "string" ? { slackUserId: value.slackUserId } : {},
2696
- ...typeof value.slackUserName === "string" ? { slackUserName: value.slackUserName } : {}
2697
- };
2698
- return Object.keys(requester).length > 0 ? requester : void 0;
2774
+ function parseOriginRequester(value) {
2775
+ return parseStoredSlackRequester(value);
2699
2776
  }
2700
2777
  function parseOriginSurface(value) {
2701
2778
  if (value === "slack" || value === "api" || value === "scheduler" || value === "internal") {
@@ -2718,7 +2795,7 @@ function parseContext(value) {
2718
2795
  return {
2719
2796
  ...typeof value.channelName === "string" && value.channelName.trim() ? { channelName: value.channelName.trim() } : {},
2720
2797
  ...parseOriginSurface(value.originSurface) ? { originSurface: parseOriginSurface(value.originSurface) } : {},
2721
- ...parseAgentTurnRequester2(value.originRequester) ? { originRequester: parseAgentTurnRequester2(value.originRequester) } : {},
2798
+ ...parseOriginRequester(value.originRequester) ? { originRequester: parseOriginRequester(value.originRequester) } : {},
2722
2799
  startedAtMs
2723
2800
  };
2724
2801
  }
@@ -2827,7 +2904,6 @@ export {
2827
2904
  getAgentTurnSessionRecord,
2828
2905
  upsertAgentTurnSessionRecord,
2829
2906
  recordAgentTurnSessionSummary,
2830
- listAgentTurnSessionSummaries,
2831
2907
  listAgentTurnSessionSummariesForConversation,
2832
2908
  abandonAgentTurnSessionRecord,
2833
2909
  failAgentTurnSessionRecord,
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  getSlackBotToken
3
- } from "./chunk-JS4HURDT.js";
3
+ } from "./chunk-ZJQPA67D.js";
4
4
  import {
5
+ isSlackConversationId,
6
+ isSlackTeamId,
5
7
  logWarn
6
- } from "./chunk-BBXYXOJW.js";
8
+ } from "./chunk-6GEYPE6T.js";
7
9
 
8
10
  // src/chat/slack/client.ts
9
11
  import { WebClient } from "@slack/web-api";
@@ -276,16 +278,6 @@ async function downloadPrivateSlackFile(url) {
276
278
 
277
279
  // src/chat/destination.ts
278
280
  import { destinationSchema } from "@sentry/junior-plugin-api";
279
-
280
- // src/chat/slack/ids.ts
281
- function isSlackTeamId(value) {
282
- return /^T[A-Z0-9]+$/.test(value);
283
- }
284
- function isSlackConversationId(value) {
285
- return /^(C|G|D)[A-Z0-9]+$/.test(value);
286
- }
287
-
288
- // src/chat/destination.ts
289
281
  function createSlackDestination(input) {
290
282
  const channelId = normalizeSlackConversationId(input.channelId);
291
283
  const teamId = input.teamId?.trim();
@@ -6,7 +6,31 @@ import {
6
6
  setSpanAttributes,
7
7
  toOptionalString,
8
8
  withSpan
9
- } from "./chunk-BBXYXOJW.js";
9
+ } from "./chunk-6GEYPE6T.js";
10
+
11
+ // src/chat/config.ts
12
+ import { getModel } from "@earendil-works/pi-ai";
13
+
14
+ // src/chat/optional-string.ts
15
+ function toOptionalTrimmed(value) {
16
+ if (!value) {
17
+ return void 0;
18
+ }
19
+ const trimmed = value.trim();
20
+ return trimmed.length > 0 ? trimmed : void 0;
21
+ }
22
+
23
+ // src/chat/pi/client.ts
24
+ import {
25
+ completeSimple,
26
+ getEnvApiKey,
27
+ getModels,
28
+ registerApiProvider
29
+ } from "@earendil-works/pi-ai";
30
+ import {
31
+ streamAnthropic,
32
+ streamSimpleAnthropic
33
+ } from "@earendil-works/pi-ai/anthropic";
10
34
 
11
35
  // src/chat/slack/context.ts
12
36
  function toTrimmedSlackString(value) {
@@ -207,30 +231,6 @@ function toGenAiMessagesTraceAttributes(prefix, messages) {
207
231
  };
208
232
  }
209
233
 
210
- // src/chat/config.ts
211
- import { getModel } from "@earendil-works/pi-ai";
212
-
213
- // src/chat/optional-string.ts
214
- function toOptionalTrimmed(value) {
215
- if (!value) {
216
- return void 0;
217
- }
218
- const trimmed = value.trim();
219
- return trimmed.length > 0 ? trimmed : void 0;
220
- }
221
-
222
- // src/chat/pi/client.ts
223
- import {
224
- completeSimple,
225
- getEnvApiKey,
226
- getModels,
227
- registerApiProvider
228
- } from "@earendil-works/pi-ai";
229
- import {
230
- streamAnthropic,
231
- streamSimpleAnthropic
232
- } from "@earendil-works/pi-ai/anthropic";
233
-
234
234
  // src/chat/turn-context-tag.ts
235
235
  var TURN_CONTEXT_TAG = "runtime-turn-context";
236
236
 
package/dist/cli/check.js CHANGED
@@ -1,16 +1,18 @@
1
- import {
2
- parseSkillFile
3
- } from "../chunk-GT67ZWZQ.js";
4
- import {
5
- parseInlinePluginManifest,
6
- parsePluginManifest
7
- } from "../chunk-UXG6TU2U.js";
8
1
  import {
9
2
  JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
10
3
  JUNIOR_HEARTBEAT_ROUTE,
11
4
  LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION
12
5
  } from "../chunk-6YY4Q3D4.js";
13
- import "../chunk-BBXYXOJW.js";
6
+ import {
7
+ parseSkillFile
8
+ } from "../chunk-55XEZFGD.js";
9
+ import {
10
+ parseInlinePluginManifest,
11
+ parsePluginManifest
12
+ } from "../chunk-GB3AL54K.js";
13
+ import "../chunk-KVZL5NZS.js";
14
+ import "../chunk-PP7AGSBU.js";
15
+ import "../chunk-6GEYPE6T.js";
14
16
  import "../chunk-Z3YD6NHK.js";
15
17
  import "../chunk-2KG3PWR4.js";
16
18