@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.
- package/dist/app.js +305 -129
- 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
|
|
2105
|
-
if (!
|
|
2106
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
|
|
11378
|
-
|
|
11379
|
-
|
|
11380
|
-
|
|
11381
|
-
|
|
11382
|
-
|
|
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
|
-
}
|
|
11402
|
-
|
|
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
|
-
|
|
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
|
|
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: (
|
|
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
|
-
|
|
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
|
-
|
|
11667
|
+
checkpoint,
|
|
11448
11668
|
ttlMs
|
|
11449
11669
|
);
|
|
11450
|
-
return
|
|
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 =
|
|
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
|
-
|
|
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
|
|
15299
|
+
const userMessage = getTurnUserMessage(conversation, sessionId);
|
|
15146
15300
|
clearPendingAuth(conversation, sessionId);
|
|
15147
|
-
markConversationMessage(conversation,
|
|
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
|
|
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
|
-
|
|
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, {
|