@sentry/junior 0.86.0 → 0.87.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 +4 -36
- package/dist/chat/no-reply.d.ts +7 -0
- package/dist/chat/services/reply-delivery-plan.d.ts +0 -4
- package/dist/{chunk-37B2R2QJ.js → chunk-ACJJJEGG.js} +20 -7
- package/dist/{chunk-FPHA6GCQ.js → chunk-B6FQPS7A.js} +74 -73
- package/dist/cli/chat.js +2 -2
- package/dist/reporting.js +1 -1
- package/dist/{runner-HEBRPNN2.js → runner-DMP3IQNM.js} +2 -2
- package/package.json +5 -5
package/dist/app.js
CHANGED
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
createConversationMemoryService,
|
|
18
18
|
createUserTokenStore,
|
|
19
19
|
deleteMcpAuthSession,
|
|
20
|
-
deleteSlackMessage,
|
|
21
20
|
deliverResourceEventSubscription,
|
|
22
21
|
estimateTextTokens,
|
|
23
22
|
executeCredentialedEgressRequest,
|
|
@@ -42,7 +41,6 @@ import {
|
|
|
42
41
|
isCooperativeTurnYieldError,
|
|
43
42
|
isHumanConversationMessage,
|
|
44
43
|
isPendingAuthLatestRequest,
|
|
45
|
-
isRedundantReactionAckText,
|
|
46
44
|
isRetryableTurnError,
|
|
47
45
|
isTurnInputCommitLostError,
|
|
48
46
|
isTurnInputDeferredError,
|
|
@@ -77,7 +75,7 @@ import {
|
|
|
77
75
|
updateConversationStats,
|
|
78
76
|
uploadFilesToThread,
|
|
79
77
|
upsertConversationMessage
|
|
80
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-B6FQPS7A.js";
|
|
81
79
|
import {
|
|
82
80
|
CONVERSATION_WORK_CHECK_IN_INTERVAL_MS,
|
|
83
81
|
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
@@ -139,7 +137,7 @@ import {
|
|
|
139
137
|
recordAuthorizationCompleted,
|
|
140
138
|
splitSlackReplyText,
|
|
141
139
|
truncateStatusText
|
|
142
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-ACJJJEGG.js";
|
|
143
141
|
import {
|
|
144
142
|
validatePluginEgressCredentialHooks,
|
|
145
143
|
validatePluginRegistrations
|
|
@@ -10054,16 +10052,12 @@ function createReplyToThread(deps) {
|
|
|
10054
10052
|
});
|
|
10055
10053
|
}
|
|
10056
10054
|
const artifactStatePatch = reply.artifactStatePatch ? { ...reply.artifactStatePatch } : {};
|
|
10057
|
-
const reactionPerformed = reply.diagnostics.toolCalls.includes(
|
|
10058
|
-
"slackMessageAddReaction"
|
|
10059
|
-
);
|
|
10060
10055
|
const plannedPosts = planSlackReplyPosts({ reply });
|
|
10061
10056
|
const replyFooter = buildSlackReplyFooter({
|
|
10062
10057
|
conversationId
|
|
10063
10058
|
});
|
|
10064
10059
|
const shouldUseSlackFooter = Boolean(replyFooter) && Boolean(channelId && threadTs) && thread.adapter?.name === "slack";
|
|
10065
10060
|
if (plannedPosts.length > 0) {
|
|
10066
|
-
let sent;
|
|
10067
10061
|
const hasVisibleDelivery = plannedPosts.some(
|
|
10068
10062
|
hasVisibleSlackDelivery
|
|
10069
10063
|
);
|
|
@@ -10080,7 +10074,7 @@ function createReplyToThread(deps) {
|
|
|
10080
10074
|
"Slack footer delivery requires a concrete channel and thread timestamp"
|
|
10081
10075
|
);
|
|
10082
10076
|
}
|
|
10083
|
-
|
|
10077
|
+
await postSlackApiReplyPosts({
|
|
10084
10078
|
beforePost: beforeFirstResponsePost,
|
|
10085
10079
|
channelId: slackChannelId,
|
|
10086
10080
|
threadTs: slackThreadTs,
|
|
@@ -10101,24 +10095,12 @@ function createReplyToThread(deps) {
|
|
|
10101
10095
|
);
|
|
10102
10096
|
}
|
|
10103
10097
|
});
|
|
10104
|
-
if (sentMessageTs) {
|
|
10105
|
-
sent = {
|
|
10106
|
-
id: sentMessageTs,
|
|
10107
|
-
text: reply.text,
|
|
10108
|
-
delete: async () => {
|
|
10109
|
-
await deleteSlackMessage({
|
|
10110
|
-
channelId: slackChannelId,
|
|
10111
|
-
timestamp: sentMessageTs
|
|
10112
|
-
});
|
|
10113
|
-
}
|
|
10114
|
-
};
|
|
10115
|
-
}
|
|
10116
10098
|
} else {
|
|
10117
10099
|
for (const post of plannedPosts) {
|
|
10118
10100
|
if (!hasVisibleSlackDelivery(post)) {
|
|
10119
10101
|
continue;
|
|
10120
10102
|
}
|
|
10121
|
-
|
|
10103
|
+
await postThreadReply(
|
|
10122
10104
|
buildSlackOutputMessage(post.text, post.files),
|
|
10123
10105
|
post.stage
|
|
10124
10106
|
);
|
|
@@ -10126,20 +10108,6 @@ function createReplyToThread(deps) {
|
|
|
10126
10108
|
}
|
|
10127
10109
|
finalReplyDelivered = true;
|
|
10128
10110
|
shouldPersistFailureState = false;
|
|
10129
|
-
const firstPlannedMessageHasFiles = (plannedPosts[0]?.files?.length ?? 0) > 0;
|
|
10130
|
-
if (sent && reactionPerformed && plannedPosts.length === 1 && !firstPlannedMessageHasFiles && isRedundantReactionAckText(reply.text)) {
|
|
10131
|
-
try {
|
|
10132
|
-
await sent.delete();
|
|
10133
|
-
} catch (error) {
|
|
10134
|
-
logException(
|
|
10135
|
-
error,
|
|
10136
|
-
"slack_redundant_ack_delete_failed",
|
|
10137
|
-
turnTraceContext,
|
|
10138
|
-
messageTs ? { "messaging.message.id": messageTs } : {},
|
|
10139
|
-
"Failed to delete redundant reaction-ack reply"
|
|
10140
|
-
);
|
|
10141
|
-
}
|
|
10142
|
-
}
|
|
10143
10111
|
} else {
|
|
10144
10112
|
finalReplyDelivered = true;
|
|
10145
10113
|
shouldPersistFailureState = false;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const NO_REPLY_MARKER = "[[NO_REPLY]]";
|
|
2
|
+
/** Detect the reserved marker so Slack side effects can intentionally complete without thread text. */
|
|
3
|
+
export declare function isNoReplyMarker(text: string): boolean;
|
|
4
|
+
/** Detect marker leaks before publication strips or rejects them. */
|
|
5
|
+
export declare function containsNoReplyMarker(text: string): boolean;
|
|
6
|
+
/** Remove the reserved marker from mixed assistant text so it is never shown to users. */
|
|
7
|
+
export declare function stripNoReplyMarker(text: string): string;
|
|
@@ -5,10 +5,6 @@ export interface ReplyDeliveryPlan {
|
|
|
5
5
|
postThreadText: boolean;
|
|
6
6
|
attachFiles: ReplyFileDelivery;
|
|
7
7
|
}
|
|
8
|
-
/** Check if text is a short acknowledgment (emoji, "ok", etc.) that a reaction already covers. */
|
|
9
|
-
export declare function isRedundantReactionAckText(text: string): boolean;
|
|
10
|
-
/** Check if the user asked for a reaction without also asking for text. */
|
|
11
|
-
export declare function isReactionOnlyIntent(text: string): boolean;
|
|
12
8
|
/** Determine how a reply should be delivered (thread vs channel, file handling). */
|
|
13
9
|
export declare function buildReplyDeliveryPlan(args: {
|
|
14
10
|
explicitChannelPostIntent: boolean;
|
|
@@ -669,6 +669,18 @@ function getInterruptionMarker() {
|
|
|
669
669
|
import fs from "fs";
|
|
670
670
|
import path from "path";
|
|
671
671
|
|
|
672
|
+
// src/chat/no-reply.ts
|
|
673
|
+
var NO_REPLY_MARKER = "[[NO_REPLY]]";
|
|
674
|
+
function isNoReplyMarker(text) {
|
|
675
|
+
return text.trim() === NO_REPLY_MARKER;
|
|
676
|
+
}
|
|
677
|
+
function containsNoReplyMarker(text) {
|
|
678
|
+
return text.includes(NO_REPLY_MARKER);
|
|
679
|
+
}
|
|
680
|
+
function stripNoReplyMarker(text) {
|
|
681
|
+
return text.replaceAll(NO_REPLY_MARKER, "").trim();
|
|
682
|
+
}
|
|
683
|
+
|
|
672
684
|
// src/chat/slack/status-format.ts
|
|
673
685
|
var SLACK_STATUS_MAX_LENGTH = 50;
|
|
674
686
|
function truncateStatusText(text) {
|
|
@@ -1360,12 +1372,10 @@ var CONVERSATION_RULES = [
|
|
|
1360
1372
|
"- Runtime owns continuation and authorization notices; on resumed turns, answer with the final requested content only."
|
|
1361
1373
|
];
|
|
1362
1374
|
var SLACK_ACTION_RULES = [
|
|
1363
|
-
"-
|
|
1364
|
-
"- Use
|
|
1365
|
-
"-
|
|
1366
|
-
|
|
1367
|
-
"- Do not claim an attachment, canvas, channel post, list update, or reaction succeeded unless the tool returned success this turn; when it did, include any link the tool returned.",
|
|
1368
|
-
"- Do not use reactions as progress indicators."
|
|
1375
|
+
"- Slack tools target the current runtime context; if the requested Slack target differs, explain the limitation instead of calling the tool.",
|
|
1376
|
+
"- Use channel-post and emoji-reaction tools only for explicit user-requested Slack side effects.",
|
|
1377
|
+
"- Ambient reaction requests target the current inbound message; do not ask for a message reference.",
|
|
1378
|
+
`- Side-effect-only completion for channel posts or reactions: call the requested tool first; if it succeeds and fully satisfies the request, final message must be exactly ${NO_REPLY_MARKER}.`
|
|
1369
1379
|
];
|
|
1370
1380
|
var SAFETY_RULES = [
|
|
1371
1381
|
"- Stay within the user's request and the runtime's available capabilities; do not pursue independent goals, persistence, replication, credential gathering, or access expansion.",
|
|
@@ -1416,7 +1426,7 @@ function buildOutputSection(platform) {
|
|
|
1416
1426
|
"- Use Slack-flavored Markdown: **bold** section labels, `code`, [text](url) links, bullet lists, and fenced code blocks. No hash-prefixed headings and no tables. When the answer primarily lists several URLs, show each URL bare instead of as a labeled link.",
|
|
1417
1427
|
"- Keep replies brief and scannable; use bullets or short code blocks when helpful, and one compact thread reply when it fits.",
|
|
1418
1428
|
"- When a research or document-style answer would benefit from continuation, multiple sections, or future reference value, create a Slack canvas and keep the thread reply to one or two short sentences plus the link; do not recap the canvas contents.",
|
|
1419
|
-
"-
|
|
1429
|
+
"- End every turn with a final user-facing markdown response unless the Slack action rules allow a side-effect-only completion.",
|
|
1420
1430
|
"</output>"
|
|
1421
1431
|
].join("\n");
|
|
1422
1432
|
}
|
|
@@ -2185,6 +2195,9 @@ async function failAgentTurnSessionRecord(args) {
|
|
|
2185
2195
|
}
|
|
2186
2196
|
|
|
2187
2197
|
export {
|
|
2198
|
+
isNoReplyMarker,
|
|
2199
|
+
containsNoReplyMarker,
|
|
2200
|
+
stripNoReplyMarker,
|
|
2188
2201
|
getInterruptionMarker,
|
|
2189
2202
|
truncateStatusText,
|
|
2190
2203
|
normalizeSlackStatusText,
|
|
@@ -22,16 +22,19 @@ import {
|
|
|
22
22
|
buildPluginSystemPromptContributions,
|
|
23
23
|
buildSystemPrompt,
|
|
24
24
|
buildTurnContextPrompt,
|
|
25
|
+
containsNoReplyMarker,
|
|
25
26
|
getAgentTurnSessionRecord,
|
|
26
27
|
getInterruptionMarker,
|
|
28
|
+
isNoReplyMarker,
|
|
27
29
|
loadConnectedMcpProviders,
|
|
28
30
|
recordAuthorizationRequested,
|
|
29
31
|
recordMcpProviderConnected,
|
|
30
32
|
recordSubagentEnded,
|
|
31
33
|
recordSubagentStarted,
|
|
32
34
|
recordToolExecutionStarted,
|
|
35
|
+
stripNoReplyMarker,
|
|
33
36
|
upsertAgentTurnSessionRecord
|
|
34
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-ACJJJEGG.js";
|
|
35
38
|
import {
|
|
36
39
|
createPluginEmbedder,
|
|
37
40
|
createPluginHookRunner,
|
|
@@ -4943,31 +4946,6 @@ async function postSlackMessage(input) {
|
|
|
4943
4946
|
} : {}
|
|
4944
4947
|
};
|
|
4945
4948
|
}
|
|
4946
|
-
async function deleteSlackMessage(input) {
|
|
4947
|
-
const channelId = requireSlackConversationId(
|
|
4948
|
-
input.channelId,
|
|
4949
|
-
"Slack message deletion"
|
|
4950
|
-
);
|
|
4951
|
-
const timestamp = requireSlackMessageTimestamp(
|
|
4952
|
-
input.timestamp,
|
|
4953
|
-
"Slack message deletion"
|
|
4954
|
-
);
|
|
4955
|
-
await withSlackRetries(
|
|
4956
|
-
() => getSlackClient().chat.delete({
|
|
4957
|
-
channel: channelId,
|
|
4958
|
-
ts: timestamp
|
|
4959
|
-
}),
|
|
4960
|
-
3,
|
|
4961
|
-
{
|
|
4962
|
-
action: "chat.delete",
|
|
4963
|
-
idempotent: true,
|
|
4964
|
-
spanAttributes: {
|
|
4965
|
-
"app.slack.channel_id": channelId,
|
|
4966
|
-
"app.slack.message_ts": timestamp
|
|
4967
|
-
}
|
|
4968
|
-
}
|
|
4969
|
-
);
|
|
4970
|
-
}
|
|
4971
4949
|
async function postSlackEphemeralMessage(input) {
|
|
4972
4950
|
const channelId = requireSlackConversationId(
|
|
4973
4951
|
input.channelId,
|
|
@@ -5144,7 +5122,7 @@ function createOperationKey(toolName, input) {
|
|
|
5144
5122
|
// src/chat/tools/slack/channel-post-message.ts
|
|
5145
5123
|
function createSlackChannelPostMessageTool(context, state) {
|
|
5146
5124
|
return tool({
|
|
5147
|
-
description: "Post a new top-level message to the current Slack channel. Use only when the user explicitly asks to post/send/share/say something to the channel. Do not use for thread replies, inline @mentions, or pinging mentioned users.",
|
|
5125
|
+
description: "Post a new top-level message to the current Slack channel. Use only when the user explicitly asks to post/send/share/say something to the current channel. Do not use for other named channels, thread replies, inline @mentions, or pinging mentioned users.",
|
|
5148
5126
|
inputSchema: Type15.Object({
|
|
5149
5127
|
text: Type15.String({
|
|
5150
5128
|
minLength: 1,
|
|
@@ -5189,7 +5167,7 @@ function createSlackChannelPostMessageTool(context, state) {
|
|
|
5189
5167
|
import { Type as Type16 } from "@sinclair/typebox";
|
|
5190
5168
|
function createSlackMessageAddReactionTool(context, state) {
|
|
5191
5169
|
return tool({
|
|
5192
|
-
description: "Add an emoji reaction to the current inbound Slack message. Use
|
|
5170
|
+
description: "Add an emoji reaction to the current inbound Slack message. Use when the user asks for a reaction on the current message without another target. Provide a Slack emoji alias name (for example `thumbsup`, `white_check_mark`, or `thumbsup::skin-tone-6`), not a unicode emoji glyph. The target message is injected by runtime context; do not use this for arbitrary historical messages.",
|
|
5193
5171
|
inputSchema: Type16.Object({
|
|
5194
5172
|
emoji: Type16.String({
|
|
5195
5173
|
minLength: 1,
|
|
@@ -5201,17 +5179,15 @@ function createSlackMessageAddReactionTool(context, state) {
|
|
|
5201
5179
|
const targetChannelId = context.sourceChannelId;
|
|
5202
5180
|
const targetMessageTs = context.messageTs;
|
|
5203
5181
|
if (!targetMessageTs) {
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
};
|
|
5182
|
+
throw new ToolInputError(
|
|
5183
|
+
"No active message timestamp is available for reactions."
|
|
5184
|
+
);
|
|
5208
5185
|
}
|
|
5209
5186
|
const normalizedEmoji = normalizeSlackEmojiName(emoji);
|
|
5210
5187
|
if (!normalizedEmoji) {
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
};
|
|
5188
|
+
throw new ToolInputError(
|
|
5189
|
+
"Emoji must be a valid Slack emoji alias name (for example `thumbsup` or `thumbsup::skin-tone-6`)."
|
|
5190
|
+
);
|
|
5215
5191
|
}
|
|
5216
5192
|
const operationKey = createOperationKey("slackMessageAddReaction", {
|
|
5217
5193
|
channel_id: targetChannelId,
|
|
@@ -10955,33 +10931,6 @@ function createAgentTools(tools, sandbox, spanContext, onStatus, sandboxExecutor
|
|
|
10955
10931
|
}
|
|
10956
10932
|
|
|
10957
10933
|
// src/chat/services/reply-delivery-plan.ts
|
|
10958
|
-
var REACTION_ONLY_ACK_RE = /^(?::[a-z0-9_+-]+:|[\p{Extended_Pictographic}\uFE0F\u200D]+)$/u;
|
|
10959
|
-
var REDUNDANT_REACTION_ACK_TEXT = ["done", "got it", "ok", "okay"];
|
|
10960
|
-
var REACTION_INTENT_RE = /\b(react|reaction|emoji|thumbs?\s*up|acknowledge)\b/i;
|
|
10961
|
-
var REACTION_WITH_REPLY_INTENT_RE = /\b(confirm|explain|reply|respond|say|tell|summari[sz]e|why)\b/i;
|
|
10962
|
-
function normalizeReactionAckText(text) {
|
|
10963
|
-
return text.trim().toLowerCase().replace(/[!.]+$/g, "");
|
|
10964
|
-
}
|
|
10965
|
-
function isRedundantReactionAckText(text) {
|
|
10966
|
-
const trimmed = text.trim();
|
|
10967
|
-
if (!trimmed) {
|
|
10968
|
-
return false;
|
|
10969
|
-
}
|
|
10970
|
-
if (REACTION_ONLY_ACK_RE.test(trimmed)) {
|
|
10971
|
-
return true;
|
|
10972
|
-
}
|
|
10973
|
-
const normalized = normalizeReactionAckText(text);
|
|
10974
|
-
return REDUNDANT_REACTION_ACK_TEXT.includes(
|
|
10975
|
-
normalized
|
|
10976
|
-
);
|
|
10977
|
-
}
|
|
10978
|
-
function isReactionOnlyIntent(text) {
|
|
10979
|
-
const normalized = text.trim();
|
|
10980
|
-
if (!normalized) {
|
|
10981
|
-
return false;
|
|
10982
|
-
}
|
|
10983
|
-
return REACTION_INTENT_RE.test(normalized) && !REACTION_WITH_REPLY_INTENT_RE.test(normalized);
|
|
10984
|
-
}
|
|
10985
10934
|
function buildReplyDeliveryPlan(args) {
|
|
10986
10935
|
const mode = args.explicitChannelPostIntent && args.channelPostPerformed ? "channel_only" : "thread";
|
|
10987
10936
|
let attachFiles = "none";
|
|
@@ -11095,9 +11044,12 @@ function buildTurnResult(input) {
|
|
|
11095
11044
|
const toolResults = newMessages.filter(isToolResultMessage);
|
|
11096
11045
|
const assistantMessages = newMessages.filter(isAssistantMessage);
|
|
11097
11046
|
const terminalAssistantMessages = getTerminalAssistantMessages(newMessages);
|
|
11098
|
-
const
|
|
11047
|
+
const rawPrimaryText = stripThinkingXmlBlocks(
|
|
11099
11048
|
terminalAssistantMessages.map((message) => extractAssistantText(message)).join("\n\n")
|
|
11100
11049
|
).trim();
|
|
11050
|
+
const exactNoReplyMarker = isNoReplyMarker(rawPrimaryText);
|
|
11051
|
+
const mixedNoReplyMarker = !exactNoReplyMarker && containsNoReplyMarker(rawPrimaryText);
|
|
11052
|
+
const primaryText = exactNoReplyMarker ? "" : mixedNoReplyMarker ? stripNoReplyMarker(rawPrimaryText) : rawPrimaryText;
|
|
11101
11053
|
const toolErrorCount = toolResults.filter((result) => result.isError).length;
|
|
11102
11054
|
const explicitChannelPostIntent = isExplicitChannelPostIntent(userInput);
|
|
11103
11055
|
const successfulToolNames = new Set(
|
|
@@ -11108,17 +11060,67 @@ function buildTurnResult(input) {
|
|
|
11108
11060
|
);
|
|
11109
11061
|
const canvasCreated = successfulToolNames.has("slackCanvasCreate");
|
|
11110
11062
|
const reactionPerformed = successfulToolNames.has("slackMessageAddReaction");
|
|
11063
|
+
const markerSideEffectSuccess = exactNoReplyMarker && toolErrorCount === 0 && (reactionPerformed || channelPostPerformed || replyFiles.length > 0);
|
|
11064
|
+
const fileOnlySuccess = !rawPrimaryText && toolErrorCount === 0 && replyFiles.length > 0;
|
|
11065
|
+
const sideEffectOnlySuccess = markerSideEffectSuccess || fileOnlySuccess;
|
|
11111
11066
|
const baseDeliveryPlan = buildReplyDeliveryPlan({
|
|
11112
|
-
explicitChannelPostIntent,
|
|
11067
|
+
explicitChannelPostIntent: exactNoReplyMarker && explicitChannelPostIntent,
|
|
11113
11068
|
channelPostPerformed,
|
|
11114
11069
|
hasFiles: replyFiles.length > 0
|
|
11115
11070
|
});
|
|
11116
|
-
const sideEffectOnlySuccess = !primaryText && toolErrorCount === 0 && (reactionPerformed || channelPostPerformed || replyFiles.length > 0);
|
|
11117
11071
|
const lastAssistant = terminalAssistantMessages.at(-1);
|
|
11118
11072
|
const stopReason = typeof lastAssistant?.stopReason === "string" ? lastAssistant.stopReason : void 0;
|
|
11119
11073
|
const errorMessage = typeof lastAssistant?.errorMessage === "string" ? lastAssistant.errorMessage : void 0;
|
|
11120
11074
|
const isProviderError = stopReason === "error";
|
|
11121
|
-
if (
|
|
11075
|
+
if (exactNoReplyMarker) {
|
|
11076
|
+
const markerCategory = reactionPerformed ? "reaction" : channelPostPerformed ? "channel_post" : replyFiles.length > 0 ? "file" : "none";
|
|
11077
|
+
const markerContext = {
|
|
11078
|
+
slackThreadId: correlation?.threadId,
|
|
11079
|
+
slackUserId: correlation?.requesterId,
|
|
11080
|
+
slackChannelId: correlation?.channelId,
|
|
11081
|
+
runId: correlation?.runId,
|
|
11082
|
+
assistantUserName,
|
|
11083
|
+
modelId: botConfig.modelId
|
|
11084
|
+
};
|
|
11085
|
+
const markerAttributes = {
|
|
11086
|
+
"app.ai.no_reply_marker": true,
|
|
11087
|
+
"app.ai.no_reply_marker_category": markerCategory,
|
|
11088
|
+
"app.ai.no_reply_marker_accepted": sideEffectOnlySuccess && !isProviderError
|
|
11089
|
+
};
|
|
11090
|
+
if (sideEffectOnlySuccess && !isProviderError) {
|
|
11091
|
+
logInfo(
|
|
11092
|
+
"ai_no_reply_marker_accepted",
|
|
11093
|
+
markerContext,
|
|
11094
|
+
markerAttributes,
|
|
11095
|
+
"No-reply marker suppressed visible thread text"
|
|
11096
|
+
);
|
|
11097
|
+
} else if (!isProviderError) {
|
|
11098
|
+
logWarn(
|
|
11099
|
+
"ai_no_reply_marker_rejected",
|
|
11100
|
+
markerContext,
|
|
11101
|
+
markerAttributes,
|
|
11102
|
+
"No-reply marker requires a successful visible side effect"
|
|
11103
|
+
);
|
|
11104
|
+
}
|
|
11105
|
+
} else if (mixedNoReplyMarker) {
|
|
11106
|
+
logWarn(
|
|
11107
|
+
"ai_no_reply_marker_mixed_text",
|
|
11108
|
+
{
|
|
11109
|
+
slackThreadId: correlation?.threadId,
|
|
11110
|
+
slackUserId: correlation?.requesterId,
|
|
11111
|
+
slackChannelId: correlation?.channelId,
|
|
11112
|
+
runId: correlation?.runId,
|
|
11113
|
+
assistantUserName,
|
|
11114
|
+
modelId: botConfig.modelId
|
|
11115
|
+
},
|
|
11116
|
+
{
|
|
11117
|
+
"app.ai.no_reply_marker": true,
|
|
11118
|
+
"app.ai.no_reply_marker_mode": "mixed"
|
|
11119
|
+
},
|
|
11120
|
+
"No-reply marker appeared with visible assistant text"
|
|
11121
|
+
);
|
|
11122
|
+
}
|
|
11123
|
+
if (!primaryText && !sideEffectOnlySuccess && !isProviderError && !exactNoReplyMarker) {
|
|
11122
11124
|
logWarn(
|
|
11123
11125
|
"ai_model_response_empty",
|
|
11124
11126
|
{
|
|
@@ -11137,7 +11139,7 @@ function buildTurnResult(input) {
|
|
|
11137
11139
|
"Model returned empty text response"
|
|
11138
11140
|
);
|
|
11139
11141
|
}
|
|
11140
|
-
const usedPrimaryText = Boolean(
|
|
11142
|
+
const usedPrimaryText = Boolean(rawPrimaryText);
|
|
11141
11143
|
let outcome;
|
|
11142
11144
|
if (isProviderError) {
|
|
11143
11145
|
outcome = "provider_error";
|
|
@@ -11146,8 +11148,7 @@ function buildTurnResult(input) {
|
|
|
11146
11148
|
} else {
|
|
11147
11149
|
outcome = "execution_failure";
|
|
11148
11150
|
}
|
|
11149
|
-
const
|
|
11150
|
-
const rawResponseText = suppressReactionOnlyText ? "" : primaryText;
|
|
11151
|
+
const rawResponseText = primaryText;
|
|
11151
11152
|
const responseText = canvasCreated && isVerbosePostCanvasReply(rawResponseText) ? buildBriefPostCanvasReply(artifactStatePatch) : rawResponseText;
|
|
11152
11153
|
const escapedOrRawPayload = Boolean(primaryText) && (isExecutionEscapeResponse(primaryText) || isRawToolPayloadResponse(primaryText));
|
|
11153
11154
|
const resolvedText = escapedOrRawPayload ? "" : enforceAttachmentClaimTruth(responseText, replyFiles.length > 0);
|
|
@@ -14911,6 +14912,7 @@ async function processPluginTask(message, options = {}) {
|
|
|
14911
14912
|
}
|
|
14912
14913
|
|
|
14913
14914
|
// src/chat/runtime/delivered-turn-state.ts
|
|
14915
|
+
var NO_VISIBLE_REPLY_CONVERSATION_TEXT = "[no visible reply]";
|
|
14914
14916
|
function buildDeliveredTurnStatePatch(args) {
|
|
14915
14917
|
const conversation = structuredClone(args.conversation);
|
|
14916
14918
|
const artifactStatePatch = {
|
|
@@ -14919,6 +14921,7 @@ function buildDeliveredTurnStatePatch(args) {
|
|
|
14919
14921
|
};
|
|
14920
14922
|
const artifacts = Object.keys(artifactStatePatch).length > 0 ? mergeArtifactsState(args.artifacts, artifactStatePatch) : void 0;
|
|
14921
14923
|
clearPendingAuth(conversation, args.sessionId);
|
|
14924
|
+
const assistantText = normalizeConversationText(args.reply.text) || (args.reply.deliveryPlan?.postThreadText === false ? NO_VISIBLE_REPLY_CONVERSATION_TEXT : "[empty response]");
|
|
14922
14925
|
markConversationMessage(conversation, args.userMessageId, {
|
|
14923
14926
|
replied: true,
|
|
14924
14927
|
skippedReason: void 0
|
|
@@ -14926,7 +14929,7 @@ function buildDeliveredTurnStatePatch(args) {
|
|
|
14926
14929
|
upsertConversationMessage(conversation, {
|
|
14927
14930
|
id: generateConversationId("assistant"),
|
|
14928
14931
|
role: "assistant",
|
|
14929
|
-
text:
|
|
14932
|
+
text: assistantText,
|
|
14930
14933
|
createdAtMs: Date.now(),
|
|
14931
14934
|
author: {
|
|
14932
14935
|
userName: botConfig.userName,
|
|
@@ -14958,7 +14961,6 @@ export {
|
|
|
14958
14961
|
deliverResourceEventSubscription,
|
|
14959
14962
|
listThreadReplies,
|
|
14960
14963
|
postSlackMessage,
|
|
14961
|
-
deleteSlackMessage,
|
|
14962
14964
|
uploadFilesToThread,
|
|
14963
14965
|
addReactionToMessage,
|
|
14964
14966
|
removeReactionFromMessage,
|
|
@@ -15002,7 +15004,6 @@ export {
|
|
|
15002
15004
|
startActiveTurn,
|
|
15003
15005
|
markTurnClosed,
|
|
15004
15006
|
markTurnFailed,
|
|
15005
|
-
isRedundantReactionAckText,
|
|
15006
15007
|
persistCompletedSessionRecord,
|
|
15007
15008
|
completeDeliveredTurn,
|
|
15008
15009
|
persistYieldSessionRecord,
|
package/dist/cli/chat.js
CHANGED
|
@@ -195,7 +195,7 @@ async function runPrompt(options, io, pluginSet) {
|
|
|
195
195
|
defaultStateAdapterForLocalChat();
|
|
196
196
|
await configureLocalChatPlugins(pluginSet);
|
|
197
197
|
const conversationId = newRunConversationId();
|
|
198
|
-
const { runLocalAgentTurn } = await import("../runner-
|
|
198
|
+
const { runLocalAgentTurn } = await import("../runner-DMP3IQNM.js");
|
|
199
199
|
const result = await runLocalAgentTurn(
|
|
200
200
|
{
|
|
201
201
|
conversationId,
|
|
@@ -219,7 +219,7 @@ async function runInteractive(io, pluginSet) {
|
|
|
219
219
|
defaultStateAdapterForLocalChat();
|
|
220
220
|
await configureLocalChatPlugins(pluginSet);
|
|
221
221
|
const conversationId = newRunConversationId();
|
|
222
|
-
const { runLocalAgentTurn } = await import("../runner-
|
|
222
|
+
const { runLocalAgentTurn } = await import("../runner-DMP3IQNM.js");
|
|
223
223
|
const rl = readline.createInterface({
|
|
224
224
|
input: io.input,
|
|
225
225
|
output: io.output,
|
package/dist/reporting.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
startActiveTurn,
|
|
17
17
|
updateConversationStats,
|
|
18
18
|
upsertConversationMessage
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-B6FQPS7A.js";
|
|
20
20
|
import {
|
|
21
21
|
coerceThreadConversationState
|
|
22
22
|
} from "./chunk-66NX7MNW.js";
|
|
@@ -25,7 +25,7 @@ import "./chunk-KNFROR7R.js";
|
|
|
25
25
|
import {
|
|
26
26
|
commitMessages,
|
|
27
27
|
loadProjection
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-ACJJJEGG.js";
|
|
29
29
|
import "./chunk-2NFV5FMB.js";
|
|
30
30
|
import "./chunk-BRSQQRG6.js";
|
|
31
31
|
import "./chunk-6I6HBOQM.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"pg": "^8.16.3",
|
|
71
71
|
"yaml": "^2.9.0",
|
|
72
72
|
"zod": "^4.4.3",
|
|
73
|
-
"@sentry/junior-plugin-api": "0.
|
|
73
|
+
"@sentry/junior-plugin-api": "0.87.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@emnapi/core": "^1.10.0",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"typescript": "^6.0.3",
|
|
87
87
|
"vercel": "^54.4.0",
|
|
88
88
|
"vitest": "^4.1.7",
|
|
89
|
-
"@sentry/junior-
|
|
90
|
-
"@sentry/junior-
|
|
89
|
+
"@sentry/junior-memory": "0.87.0",
|
|
90
|
+
"@sentry/junior-github": "0.87.0",
|
|
91
91
|
"@sentry/junior-testing": "0.0.0",
|
|
92
|
-
"@sentry/junior-scheduler": "0.
|
|
92
|
+
"@sentry/junior-scheduler": "0.87.0"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
95
95
|
"build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
|