@sentry/junior 0.52.0 → 0.53.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 (2) hide show
  1. package/dist/app.js +305 -129
  2. package/package.json +1 -1
package/dist/app.js CHANGED
@@ -494,6 +494,7 @@ function coerceThreadConversationState(value) {
494
494
  const processing = {
495
495
  activeTurnId: toOptionalString(rawProcessing.activeTurnId),
496
496
  lastCompletedAtMs: toOptionalNumber(rawProcessing.lastCompletedAtMs),
497
+ lastSessionId: toOptionalString(rawProcessing.lastSessionId),
497
498
  pendingAuth: coercePendingAuthState(rawProcessing.pendingAuth)
498
499
  };
499
500
  const rawStats = isRecord(rawConversation.stats) ? rawConversation.stats : {};
@@ -2101,17 +2102,24 @@ function startActiveTurn(args) {
2101
2102
  args.conversation.processing.activeTurnId = args.nextTurnId;
2102
2103
  args.updateConversationStats(args.conversation);
2103
2104
  }
2104
- function markTurnCompleted(args) {
2105
- if (!args.sessionId || args.conversation.processing.activeTurnId === args.sessionId) {
2106
- args.conversation.processing.activeTurnId = void 0;
2105
+ function clearActiveTurn(conversation, sessionId) {
2106
+ if (!sessionId || conversation.processing.activeTurnId === sessionId) {
2107
+ conversation.processing.activeTurnId = void 0;
2107
2108
  }
2109
+ }
2110
+ function markTurnClosed(args) {
2111
+ clearActiveTurn(args.conversation, args.sessionId);
2112
+ args.conversation.processing.lastCompletedAtMs = args.nowMs;
2113
+ args.updateConversationStats(args.conversation);
2114
+ }
2115
+ function markTurnCompleted(args) {
2116
+ clearActiveTurn(args.conversation, args.sessionId);
2117
+ args.conversation.processing.lastSessionId = args.sessionId;
2108
2118
  args.conversation.processing.lastCompletedAtMs = args.nowMs;
2109
2119
  args.updateConversationStats(args.conversation);
2110
2120
  }
2111
2121
  function markTurnFailed(args) {
2112
- if (!args.sessionId || args.conversation.processing.activeTurnId === args.sessionId) {
2113
- args.conversation.processing.activeTurnId = void 0;
2114
- }
2122
+ clearActiveTurn(args.conversation, args.sessionId);
2115
2123
  args.conversation.processing.lastCompletedAtMs = args.nowMs;
2116
2124
  args.markConversationMessage(args.conversation, args.userMessageId, {
2117
2125
  replied: false,
@@ -2450,6 +2458,9 @@ import { Agent as Agent2 } from "@mariozechner/pi-agent-core";
2450
2458
  import fs from "fs";
2451
2459
  import path2 from "path";
2452
2460
 
2461
+ // src/chat/turn-context-tag.ts
2462
+ var TURN_CONTEXT_TAG = "runtime-turn-context";
2463
+
2453
2464
  // src/chat/interruption-marker.ts
2454
2465
  var INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
2455
2466
  function getInterruptionMarker() {
@@ -3020,7 +3031,6 @@ function formatSlackCapabilityNames(capabilities) {
3020
3031
  }
3021
3032
  var HEADER = "You are a Slack-based helper assistant. Follow the personality block for voice and tone in every reply. The behavior and output blocks define platform mechanics and override personality only when those mechanics conflict.";
3022
3033
  var TURN_CONTEXT_HEADER = "Per-turn runtime context for this request. Treat these blocks as trusted runtime facts and skill/provider instructions for the current turn; the static system prompt remains authoritative.";
3023
- var TURN_CONTEXT_TAG = "runtime-turn-context";
3024
3034
  var TOOL_POLICY_RULES = [
3025
3035
  "- Tool schemas are the source of truth for parameters; tool names are case-sensitive, so call tools exactly by their exposed names and do not invent arguments.",
3026
3036
  "- Use tools for actionable work and for facts that are mutable, external, repository-backed, provider-backed, or requested as verified/current. Stable general knowledge and already-provided context may be answered directly.",
@@ -7882,6 +7892,7 @@ import { Type as Type21 } from "@sinclair/typebox";
7882
7892
 
7883
7893
  // src/chat/respond-helpers.ts
7884
7894
  var MAX_INLINE_ATTACHMENT_BASE64_CHARS = 12e4;
7895
+ var RUNTIME_TURN_CONTEXT_START = `<${TURN_CONTEXT_TAG}>`;
7885
7896
  function getSessionIdentifiers(context) {
7886
7897
  return {
7887
7898
  conversationId: context.correlation?.conversationId ?? context.correlation?.threadId ?? context.correlation?.runId,
@@ -8044,6 +8055,75 @@ function getPiMessageRole(value) {
8044
8055
  const role = value.role;
8045
8056
  return typeof role === "string" ? role : void 0;
8046
8057
  }
8058
+ function getUserMessageContent(message) {
8059
+ const record = message;
8060
+ return record.role === "user" && Array.isArray(record.content) ? record.content : void 0;
8061
+ }
8062
+ function isRuntimeTurnContextPart(part, marker) {
8063
+ return part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.text.startsWith(marker);
8064
+ }
8065
+ function replaceRuntimeTurnContext(message, turnContextPrompt) {
8066
+ const content = getUserMessageContent(message);
8067
+ if (!content) {
8068
+ return void 0;
8069
+ }
8070
+ const marker = turnContextPrompt.split("\n", 1)[0];
8071
+ const contextIndex = content.findIndex(
8072
+ (part) => isRuntimeTurnContextPart(part, marker)
8073
+ );
8074
+ if (contextIndex < 0) {
8075
+ return void 0;
8076
+ }
8077
+ const nextContent = [...content];
8078
+ nextContent[contextIndex] = {
8079
+ ...nextContent[contextIndex],
8080
+ text: turnContextPrompt
8081
+ };
8082
+ return {
8083
+ ...message,
8084
+ content: nextContent
8085
+ };
8086
+ }
8087
+ function refreshRuntimeTurnContext(messages, turnContextPrompt) {
8088
+ for (let index = 0; index < messages.length; index += 1) {
8089
+ const updated = replaceRuntimeTurnContext(
8090
+ messages[index],
8091
+ turnContextPrompt
8092
+ );
8093
+ if (!updated) {
8094
+ continue;
8095
+ }
8096
+ const nextMessages = [...messages];
8097
+ nextMessages[index] = updated;
8098
+ return nextMessages;
8099
+ }
8100
+ return [
8101
+ ...messages,
8102
+ {
8103
+ role: "user",
8104
+ content: [{ type: "text", text: turnContextPrompt }],
8105
+ timestamp: Date.now()
8106
+ }
8107
+ ];
8108
+ }
8109
+ function stripRuntimeTurnContext(messages) {
8110
+ return messages.flatMap((message) => {
8111
+ const content = getUserMessageContent(message);
8112
+ if (!content) {
8113
+ return [message];
8114
+ }
8115
+ const nextContent = content.filter(
8116
+ (part) => !isRuntimeTurnContextPart(part, RUNTIME_TURN_CONTEXT_START)
8117
+ );
8118
+ if (nextContent.length === content.length) {
8119
+ return [message];
8120
+ }
8121
+ if (nextContent.length === 0) {
8122
+ return [];
8123
+ }
8124
+ return [{ ...message, content: nextContent }];
8125
+ });
8126
+ }
8047
8127
  function extractAssistantText(message) {
8048
8128
  const content = message.content ?? [];
8049
8129
  return content.filter(
@@ -11326,9 +11406,98 @@ async function unlinkProvider(userId, provider, userTokenStore) {
11326
11406
  ]);
11327
11407
  }
11328
11408
 
11409
+ // src/chat/state/turn-session-store.ts
11410
+ import { THREAD_STATE_TTL_MS as THREAD_STATE_TTL_MS3 } from "chat";
11411
+
11412
+ // src/chat/state/pi-session-message-store.ts
11413
+ import { isDeepStrictEqual } from "util";
11414
+ var PI_SESSION_MESSAGE_PREFIX = "junior:pi_session_message";
11415
+ function piSessionMessageKey(scope, index) {
11416
+ return `${PI_SESSION_MESSAGE_PREFIX}:${scope.conversationId}:${scope.sessionId}:${index}`;
11417
+ }
11418
+ function parsePiMessage(value) {
11419
+ return isRecord(value) ? value : void 0;
11420
+ }
11421
+ function normalizeMessageCount(value) {
11422
+ return Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
11423
+ }
11424
+ function countMatchingPrefix(left, right) {
11425
+ const limit = Math.min(left.length, right.length);
11426
+ for (let index = 0; index < limit; index += 1) {
11427
+ if (!isDeepStrictEqual(left[index], right[index])) {
11428
+ return index;
11429
+ }
11430
+ }
11431
+ return limit;
11432
+ }
11433
+ async function loadPiSessionMessages(args) {
11434
+ const stateAdapter = getStateAdapter();
11435
+ await stateAdapter.connect();
11436
+ const messageCount = normalizeMessageCount(args.messageCount);
11437
+ if (messageCount === 0) {
11438
+ return [];
11439
+ }
11440
+ const values = await Promise.all(
11441
+ Array.from(
11442
+ { length: messageCount },
11443
+ (_, index) => stateAdapter.get(piSessionMessageKey(args, index))
11444
+ )
11445
+ );
11446
+ const messages = [];
11447
+ for (const value of values) {
11448
+ const message = parsePiMessage(value);
11449
+ if (!message) {
11450
+ break;
11451
+ }
11452
+ messages.push(message);
11453
+ }
11454
+ return messages.length === messageCount ? messages : void 0;
11455
+ }
11456
+ async function loadExistingPiSessionMessages(scope, maxCount) {
11457
+ const count = normalizeMessageCount(maxCount);
11458
+ if (count === 0) {
11459
+ return [];
11460
+ }
11461
+ const stateAdapter = getStateAdapter();
11462
+ await stateAdapter.connect();
11463
+ const values = await Promise.all(
11464
+ Array.from(
11465
+ { length: count },
11466
+ (_, index) => stateAdapter.get(piSessionMessageKey(scope, index))
11467
+ )
11468
+ );
11469
+ const messages = [];
11470
+ for (const value of values) {
11471
+ const message = parsePiMessage(value);
11472
+ if (!message) {
11473
+ break;
11474
+ }
11475
+ messages.push(message);
11476
+ }
11477
+ return messages;
11478
+ }
11479
+ async function commitPiSessionMessages(args) {
11480
+ const stateAdapter = getStateAdapter();
11481
+ await stateAdapter.connect();
11482
+ const existingMessages = await loadExistingPiSessionMessages(
11483
+ { conversationId: args.conversationId, sessionId: args.sessionId },
11484
+ args.messages.length
11485
+ );
11486
+ const writeFromIndex = countMatchingPrefix(existingMessages, args.messages);
11487
+ await Promise.all(
11488
+ args.messages.slice(writeFromIndex).map(
11489
+ (message, offset) => stateAdapter.set(
11490
+ piSessionMessageKey(args, writeFromIndex + offset),
11491
+ message,
11492
+ args.ttlMs
11493
+ )
11494
+ )
11495
+ );
11496
+ }
11497
+
11329
11498
  // src/chat/state/turn-session-store.ts
11330
11499
  var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session";
11331
- var AGENT_TURN_SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
11500
+ var AGENT_TURN_SESSION_TTL_MS = THREAD_STATE_TTL_MS3;
11332
11501
  function agentTurnSessionKey(conversationId, sessionId) {
11333
11502
  return `${AGENT_TURN_SESSION_PREFIX}:${conversationId}:${sessionId}`;
11334
11503
  }
@@ -11354,41 +11523,55 @@ function parseAgentTurnUsage(value) {
11354
11523
  }
11355
11524
  return Object.keys(usage).length > 0 ? usage : void 0;
11356
11525
  }
11357
- function parseAgentTurnSessionCheckpoint(value) {
11526
+ function parseStoredRecord(value) {
11527
+ if (isRecord(value)) {
11528
+ return value;
11529
+ }
11358
11530
  if (typeof value !== "string") {
11359
11531
  return void 0;
11360
11532
  }
11361
11533
  try {
11362
11534
  const parsed = JSON.parse(value);
11363
- if (!isRecord(parsed)) {
11364
- return void 0;
11365
- }
11366
- const status = parsed.state;
11367
- if (status !== "running" && status !== "awaiting_resume" && status !== "completed" && status !== "failed" && status !== "superseded") {
11368
- return void 0;
11369
- }
11370
- const conversationId = parsed.conversationId;
11371
- const sessionId = parsed.sessionId;
11372
- const sliceId = parsed.sliceId;
11373
- const checkpointVersion = parsed.checkpointVersion;
11374
- const updatedAtMs = parsed.updatedAtMs;
11375
- const cumulativeDurationMs = toFiniteNonNegativeNumber(
11376
- parsed.cumulativeDurationMs
11377
- );
11378
- const cumulativeUsage = parseAgentTurnUsage(parsed.cumulativeUsage);
11379
- if (typeof conversationId !== "string" || typeof sessionId !== "string" || typeof sliceId !== "number" || typeof checkpointVersion !== "number" || typeof updatedAtMs !== "number") {
11380
- return void 0;
11381
- }
11382
- return {
11535
+ return isRecord(parsed) ? parsed : void 0;
11536
+ } catch {
11537
+ return void 0;
11538
+ }
11539
+ }
11540
+ function parseAgentTurnSessionRecord(value) {
11541
+ const parsed = parseStoredRecord(value);
11542
+ if (!parsed) {
11543
+ return void 0;
11544
+ }
11545
+ const status = parsed.state;
11546
+ if (status !== "running" && status !== "awaiting_resume" && status !== "completed" && status !== "failed" && status !== "superseded") {
11547
+ return void 0;
11548
+ }
11549
+ const conversationId = parsed.conversationId;
11550
+ const sessionId = parsed.sessionId;
11551
+ const sliceId = parsed.sliceId;
11552
+ const checkpointVersion = parsed.checkpointVersion;
11553
+ const updatedAtMs = parsed.updatedAtMs;
11554
+ const cumulativeDurationMs = toFiniteNonNegativeNumber(
11555
+ parsed.cumulativeDurationMs
11556
+ );
11557
+ const cumulativeUsage = parseAgentTurnUsage(parsed.cumulativeUsage);
11558
+ if (typeof conversationId !== "string" || typeof sessionId !== "string" || typeof sliceId !== "number" || typeof checkpointVersion !== "number" || typeof updatedAtMs !== "number") {
11559
+ return void 0;
11560
+ }
11561
+ const legacyPiMessages = Array.isArray(parsed.piMessages) ? parsed.piMessages : [];
11562
+ const messageCount = toFiniteNonNegativeNumber(parsed.messageCount) ?? legacyPiMessages.length;
11563
+ return {
11564
+ legacyPiMessages,
11565
+ record: {
11383
11566
  checkpointVersion,
11384
11567
  conversationId,
11385
11568
  sessionId,
11386
11569
  sliceId,
11387
11570
  state: status,
11388
11571
  updatedAtMs,
11572
+ messageCount,
11389
11573
  ...cumulativeDurationMs !== void 0 ? { cumulativeDurationMs } : {},
11390
11574
  ...cumulativeUsage ? { cumulativeUsage } : {},
11391
- piMessages: Array.isArray(parsed.piMessages) ? parsed.piMessages : [],
11392
11575
  ...Array.isArray(parsed.loadedSkillNames) ? {
11393
11576
  loadedSkillNames: parsed.loadedSkillNames.filter(
11394
11577
  (value2) => typeof value2 === "string"
@@ -11397,10 +11580,20 @@ function parseAgentTurnSessionCheckpoint(value) {
11397
11580
  ...parsed.resumeReason === "timeout" || parsed.resumeReason === "auth" ? { resumeReason: parsed.resumeReason } : {},
11398
11581
  ...typeof parsed.errorMessage === "string" ? { errorMessage: parsed.errorMessage } : {},
11399
11582
  ...typeof parsed.resumedFromSliceId === "number" ? { resumedFromSliceId: parsed.resumedFromSliceId } : {}
11400
- };
11401
- } catch {
11402
- return void 0;
11583
+ }
11584
+ };
11585
+ }
11586
+ function materializePiMessages(legacyPiMessages, messageCount, sessionMessages) {
11587
+ if (messageCount === 0) {
11588
+ return [];
11589
+ }
11590
+ if (sessionMessages) {
11591
+ return sessionMessages;
11592
+ }
11593
+ if (legacyPiMessages.length >= messageCount) {
11594
+ return legacyPiMessages.slice(0, messageCount);
11403
11595
  }
11596
+ return void 0;
11404
11597
  }
11405
11598
  async function getAgentTurnSessionCheckpoint(conversationId, sessionId) {
11406
11599
  const stateAdapter = getStateAdapter();
@@ -11408,23 +11601,51 @@ async function getAgentTurnSessionCheckpoint(conversationId, sessionId) {
11408
11601
  const value = await stateAdapter.get(
11409
11602
  agentTurnSessionKey(conversationId, sessionId)
11410
11603
  );
11411
- return parseAgentTurnSessionCheckpoint(value);
11604
+ const parsed = parseAgentTurnSessionRecord(value);
11605
+ if (!parsed) {
11606
+ return void 0;
11607
+ }
11608
+ const sessionMessages = await loadPiSessionMessages({
11609
+ conversationId,
11610
+ sessionId,
11611
+ messageCount: parsed.record.messageCount
11612
+ });
11613
+ const piMessages = materializePiMessages(
11614
+ parsed.legacyPiMessages,
11615
+ parsed.record.messageCount,
11616
+ sessionMessages
11617
+ );
11618
+ if (!piMessages) {
11619
+ return void 0;
11620
+ }
11621
+ return {
11622
+ ...parsed.record,
11623
+ piMessages
11624
+ };
11412
11625
  }
11413
11626
  async function upsertAgentTurnSessionCheckpoint(args) {
11414
11627
  const stateAdapter = getStateAdapter();
11415
11628
  await stateAdapter.connect();
11416
- const existing = await getAgentTurnSessionCheckpoint(
11417
- args.conversationId,
11418
- args.sessionId
11629
+ const existingValue = await stateAdapter.get(
11630
+ agentTurnSessionKey(args.conversationId, args.sessionId)
11419
11631
  );
11632
+ const existingRecord = parseAgentTurnSessionRecord(existingValue);
11633
+ const ttlMs = Math.max(1, args.ttlMs ?? AGENT_TURN_SESSION_TTL_MS);
11634
+ await commitPiSessionMessages({
11635
+ conversationId: args.conversationId,
11636
+ sessionId: args.sessionId,
11637
+ messages: args.piMessages,
11638
+ ttlMs
11639
+ });
11640
+ const storedMessageCount = args.piMessages.length;
11420
11641
  const checkpoint = {
11421
- checkpointVersion: (existing?.checkpointVersion ?? 0) + 1,
11642
+ checkpointVersion: (existingRecord?.record.checkpointVersion ?? 0) + 1,
11422
11643
  conversationId: args.conversationId,
11423
11644
  sessionId: args.sessionId,
11424
11645
  sliceId: args.sliceId,
11425
11646
  state: args.state,
11426
11647
  updatedAtMs: Date.now(),
11427
- piMessages: Array.isArray(args.piMessages) ? args.piMessages : [],
11648
+ messageCount: storedMessageCount,
11428
11649
  ...typeof args.cumulativeDurationMs === "number" && Number.isFinite(args.cumulativeDurationMs) ? {
11429
11650
  cumulativeDurationMs: Math.max(
11430
11651
  0,
@@ -11441,13 +11662,15 @@ async function upsertAgentTurnSessionCheckpoint(args) {
11441
11662
  ...args.errorMessage ? { errorMessage: args.errorMessage } : {},
11442
11663
  ...typeof args.resumedFromSliceId === "number" ? { resumedFromSliceId: args.resumedFromSliceId } : {}
11443
11664
  };
11444
- const ttlMs = Math.max(1, args.ttlMs ?? AGENT_TURN_SESSION_TTL_MS);
11445
11665
  await stateAdapter.set(
11446
11666
  agentTurnSessionKey(args.conversationId, args.sessionId),
11447
- JSON.stringify(checkpoint),
11667
+ checkpoint,
11448
11668
  ttlMs
11449
11669
  );
11450
- return checkpoint;
11670
+ return {
11671
+ ...checkpoint,
11672
+ piMessages: [...args.piMessages]
11673
+ };
11451
11674
  }
11452
11675
  async function supersedeAgentTurnSessionCheckpoint(args) {
11453
11676
  const existing = await getAgentTurnSessionCheckpoint(
@@ -12000,7 +12223,6 @@ function buildBriefPostCanvasReply(artifactStatePatch) {
12000
12223
  function buildTurnResult(input) {
12001
12224
  const {
12002
12225
  newMessages,
12003
- piMessages,
12004
12226
  userInput,
12005
12227
  replyFiles,
12006
12228
  artifactStatePatch,
@@ -12104,7 +12326,6 @@ function buildTurnResult(input) {
12104
12326
  text: resolvedText,
12105
12327
  files: replyFiles.length > 0 ? replyFiles : void 0,
12106
12328
  artifactStatePatch: Object.keys(artifactStatePatch).length > 0 ? artifactStatePatch : void 0,
12107
- piMessages,
12108
12329
  deliveryPlan,
12109
12330
  deliveryMode,
12110
12331
  sandboxId,
@@ -12787,69 +13008,6 @@ function buildUserTurnInput(args) {
12787
13008
  }
12788
13009
  return { routerBlocks, userContentParts };
12789
13010
  }
12790
- function refreshCheckpointTurnContext(messages, turnContextPrompt) {
12791
- const marker = getTurnContextMarker(turnContextPrompt);
12792
- for (let index = 0; index < messages.length; index += 1) {
12793
- const content = getUserMessageContent(messages[index]);
12794
- if (!content) {
12795
- continue;
12796
- }
12797
- const contextIndex = content.findIndex(
12798
- (part) => isTurnContextPart(part, marker)
12799
- );
12800
- if (contextIndex < 0) {
12801
- continue;
12802
- }
12803
- const updatedMessages = [...messages];
12804
- const updatedContent = [...content];
12805
- updatedContent[contextIndex] = {
12806
- ...updatedContent[contextIndex],
12807
- text: turnContextPrompt
12808
- };
12809
- updatedMessages[index] = {
12810
- ...messages[index],
12811
- content: updatedContent
12812
- };
12813
- return updatedMessages;
12814
- }
12815
- return [
12816
- ...messages,
12817
- {
12818
- role: "user",
12819
- content: [{ type: "text", text: turnContextPrompt }],
12820
- timestamp: Date.now()
12821
- }
12822
- ];
12823
- }
12824
- function stripTurnContextFromMessages(messages, turnContextPrompt) {
12825
- const marker = getTurnContextMarker(turnContextPrompt);
12826
- return messages.flatMap((message) => {
12827
- const content = getUserMessageContent(message);
12828
- if (!content) {
12829
- return [message];
12830
- }
12831
- const strippedContent = content.filter(
12832
- (part) => !isTurnContextPart(part, marker)
12833
- );
12834
- if (strippedContent.length === content.length) {
12835
- return [message];
12836
- }
12837
- if (strippedContent.length === 0) {
12838
- return [];
12839
- }
12840
- return [{ ...message, content: strippedContent }];
12841
- });
12842
- }
12843
- function getTurnContextMarker(turnContextPrompt) {
12844
- return turnContextPrompt.split("\n", 1)[0];
12845
- }
12846
- function getUserMessageContent(message) {
12847
- const record = message;
12848
- return record.role === "user" && Array.isArray(record.content) ? record.content : void 0;
12849
- }
12850
- function isTurnContextPart(part, marker) {
12851
- return part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.text.startsWith(marker);
12852
- }
12853
13011
  async function generateAssistantReply(messageText, context = {}) {
12854
13012
  const replyStartedAtMs = Date.now();
12855
13013
  let timeoutResumeConversationId;
@@ -13362,7 +13520,7 @@ async function generateAssistantReply(messageText, context = {}) {
13362
13520
  beforeMessageCount = agent.state.messages.length;
13363
13521
  try {
13364
13522
  if (resumedFromCheckpoint) {
13365
- agent.state.messages = refreshCheckpointTurnContext(
13523
+ agent.state.messages = refreshRuntimeTurnContext(
13366
13524
  existingCheckpoint.piMessages,
13367
13525
  turnContextPrompt
13368
13526
  );
@@ -13475,10 +13633,6 @@ async function generateAssistantReply(messageText, context = {}) {
13475
13633
  }
13476
13634
  return buildTurnResult({
13477
13635
  newMessages,
13478
- piMessages: stripTurnContextFromMessages(
13479
- agent.state.messages,
13480
- turnContextPrompt
13481
- ),
13482
13636
  userInput,
13483
13637
  replyFiles,
13484
13638
  artifactStatePatch,
@@ -14940,7 +15094,7 @@ function completeAuthPauseTurn(args) {
14940
15094
  skippedReason: void 0
14941
15095
  }
14942
15096
  );
14943
- markTurnCompleted({
15097
+ markTurnClosed({
14944
15098
  conversation: args.conversation,
14945
15099
  nowMs: Date.now(),
14946
15100
  sessionId: args.sessionId,
@@ -15142,9 +15296,9 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
15142
15296
  const conversation = coerceThreadConversationState(currentState);
15143
15297
  const artifacts = coerceThreadArtifactsState(currentState);
15144
15298
  const nextArtifacts = reply.artifactStatePatch ? mergeArtifactsState(artifacts, reply.artifactStatePatch) : void 0;
15145
- const userMessageId = getTurnUserMessageId(conversation, sessionId);
15299
+ const userMessage = getTurnUserMessage(conversation, sessionId);
15146
15300
  clearPendingAuth(conversation, sessionId);
15147
- markConversationMessage(conversation, userMessageId, {
15301
+ markConversationMessage(conversation, userMessage?.id, {
15148
15302
  replied: true,
15149
15303
  skippedReason: void 0
15150
15304
  });
@@ -15161,9 +15315,6 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
15161
15315
  replied: true
15162
15316
  }
15163
15317
  });
15164
- if (reply.piMessages) {
15165
- conversation.piMessages = reply.piMessages;
15166
- }
15167
15318
  markTurnCompleted({
15168
15319
  conversation,
15169
15320
  nowMs: Date.now(),
@@ -15585,9 +15736,6 @@ async function persistCompletedOAuthReplyState(args) {
15585
15736
  replied: true
15586
15737
  }
15587
15738
  });
15588
- if (args.reply.piMessages) {
15589
- conversation.piMessages = args.reply.piMessages;
15590
- }
15591
15739
  markTurnCompleted({
15592
15740
  conversation,
15593
15741
  nowMs: Date.now(),
@@ -16554,9 +16702,6 @@ async function persistCompletedReplyState2(args) {
16554
16702
  replied: true
16555
16703
  }
16556
16704
  });
16557
- if (args.reply.piMessages) {
16558
- conversation.piMessages = args.reply.piMessages;
16559
- }
16560
16705
  markTurnCompleted({
16561
16706
  conversation,
16562
16707
  nowMs: Date.now(),
@@ -18260,6 +18405,31 @@ function getCurrentTurnCanvasUrl(args) {
18260
18405
  function buildCanvasRecoveryReply(canvasUrl) {
18261
18406
  return `I created the canvas, but the turn was interrupted before I could finish the thread reply: ${canvasUrl}`;
18262
18407
  }
18408
+ async function loadPiMessagesForTurn(args) {
18409
+ const fallback = args.fallback.length > 0 ? [...args.fallback] : void 0;
18410
+ if (!args.conversationId) {
18411
+ return fallback;
18412
+ }
18413
+ if (args.activeTurnId) {
18414
+ const checkpoint2 = await getAgentTurnSessionCheckpoint(
18415
+ args.conversationId,
18416
+ args.activeTurnId
18417
+ );
18418
+ if (checkpoint2?.piMessages.length) {
18419
+ return stripRuntimeTurnContext(
18420
+ trimTrailingAssistantMessages(checkpoint2.piMessages)
18421
+ );
18422
+ }
18423
+ }
18424
+ if (!args.lastSessionId) {
18425
+ return fallback;
18426
+ }
18427
+ const checkpoint = await getAgentTurnSessionCheckpoint(
18428
+ args.conversationId,
18429
+ args.lastSessionId
18430
+ );
18431
+ return checkpoint?.state === "completed" && checkpoint.piMessages.length > 0 ? stripRuntimeTurnContext(checkpoint.piMessages) : fallback;
18432
+ }
18263
18433
  function createReplyToThread(deps) {
18264
18434
  return async function replyToThread(thread, message, options = {}) {
18265
18435
  if (message.author.isMe) {
@@ -18412,6 +18582,7 @@ function createReplyToThread(deps) {
18412
18582
  return;
18413
18583
  }
18414
18584
  }
18585
+ const lastSessionIdForHistory = preparedState.conversation.processing.lastSessionId;
18415
18586
  const configReply = await maybeApplyProviderDefaultConfigRequest({
18416
18587
  channelConfiguration: preparedState.channelConfiguration,
18417
18588
  requesterId: message.author.userId,
@@ -18487,6 +18658,12 @@ function createReplyToThread(deps) {
18487
18658
  }
18488
18659
  );
18489
18660
  const omittedImageAttachmentCount = !isVisionEnabled() && hasPotentialImageAttachment(message.attachments) ? countPotentialImageAttachments(message.attachments) : 0;
18661
+ const piMessages = await loadPiMessagesForTurn({
18662
+ conversationId,
18663
+ activeTurnId,
18664
+ lastSessionId: lastSessionIdForHistory,
18665
+ fallback: preparedState.conversation.piMessages
18666
+ });
18490
18667
  const status = createSlackAdapterAssistantStatusSession({
18491
18668
  channelId: assistantThreadContext?.channelId,
18492
18669
  threadTs: assistantThreadContext?.threadTs,
@@ -18538,7 +18715,7 @@ function createReplyToThread(deps) {
18538
18715
  },
18539
18716
  conversationContext: preparedState.routingContext ?? preparedState.conversationContext,
18540
18717
  artifactState: preparedState.artifacts,
18541
- piMessages: preparedState.conversation.piMessages,
18718
+ piMessages,
18542
18719
  pendingAuth: preparedState.conversation.processing.pendingAuth,
18543
18720
  configuration: preparedState.configuration,
18544
18721
  channelConfiguration: preparedState.channelConfiguration,
@@ -18621,9 +18798,6 @@ function createReplyToThread(deps) {
18621
18798
  replied: true
18622
18799
  }
18623
18800
  });
18624
- if (reply.piMessages) {
18625
- preparedState.conversation.piMessages = reply.piMessages;
18626
- }
18627
18801
  const artifactStatePatch = reply.artifactStatePatch ? { ...reply.artifactStatePatch } : {};
18628
18802
  const reactionPerformed = reply.diagnostics.toolCalls.includes(
18629
18803
  "slackMessageAddReaction"
@@ -18701,6 +18875,7 @@ function createReplyToThread(deps) {
18701
18875
  markTurnCompleted({
18702
18876
  conversation: preparedState.conversation,
18703
18877
  nowMs: Date.now(),
18878
+ sessionId: turnId,
18704
18879
  updateConversationStats
18705
18880
  });
18706
18881
  await persistThreadState(thread, {
@@ -18826,9 +19001,10 @@ function createReplyToThread(deps) {
18826
19001
  replied: true
18827
19002
  }
18828
19003
  });
18829
- markTurnCompleted({
19004
+ markTurnClosed({
18830
19005
  conversation: preparedState.conversation,
18831
19006
  nowMs: Date.now(),
19007
+ sessionId: turnId,
18832
19008
  updateConversationStats
18833
19009
  });
18834
19010
  await persistThreadState(thread, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.52.0",
3
+ "version": "0.53.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"