@sentry/junior 0.24.0 → 0.24.1
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 +256 -38
- package/dist/{chunk-J7JEFMVD.js → chunk-I3WA75AD.js} +17 -1
- package/dist/{chunk-DGN3WLA4.js → chunk-O5N42P7K.js} +1 -1
- package/dist/{chunk-B5O2EJUV.js → chunk-RMVXZMXQ.js} +1 -1
- package/dist/cli/check.js +2 -2
- package/dist/cli/snapshot-warmup.js +2 -2
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
loadSkillsByName,
|
|
7
7
|
logCapabilityCatalogLoadedOnce,
|
|
8
8
|
parseSkillInvocation
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-O5N42P7K.js";
|
|
10
10
|
import {
|
|
11
11
|
SANDBOX_DATA_ROOT,
|
|
12
12
|
SANDBOX_SKILLS_ROOT,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
sandboxSkillDir,
|
|
28
28
|
sandboxSkillFile,
|
|
29
29
|
toOptionalTrimmed
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-RMVXZMXQ.js";
|
|
31
31
|
import {
|
|
32
32
|
CredentialUnavailableError,
|
|
33
33
|
buildOAuthTokenRequest,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
createPluginBroker,
|
|
36
36
|
createRequestContext,
|
|
37
37
|
extractGenAiUsageAttributes,
|
|
38
|
+
extractGenAiUsageSummary,
|
|
38
39
|
getActiveTraceId,
|
|
39
40
|
getPluginDefinition,
|
|
40
41
|
getPluginMcpProviders,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
toOptionalString,
|
|
59
60
|
withContext,
|
|
60
61
|
withSpan
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-I3WA75AD.js";
|
|
62
63
|
import "./chunk-Z3YD6NHK.js";
|
|
63
64
|
import {
|
|
64
65
|
discoverInstalledPluginPackageContent,
|
|
@@ -1082,6 +1083,9 @@ async function postSlackMessage(input) {
|
|
|
1082
1083
|
channel: channelId,
|
|
1083
1084
|
text,
|
|
1084
1085
|
mrkdwn: true,
|
|
1086
|
+
...input.blocks?.length ? {
|
|
1087
|
+
blocks: input.blocks
|
|
1088
|
+
} : {},
|
|
1085
1089
|
...threadTs ? { thread_ts: threadTs } : {}
|
|
1086
1090
|
}),
|
|
1087
1091
|
3,
|
|
@@ -1100,6 +1104,24 @@ async function postSlackMessage(input) {
|
|
|
1100
1104
|
} : {}
|
|
1101
1105
|
};
|
|
1102
1106
|
}
|
|
1107
|
+
async function deleteSlackMessage(input) {
|
|
1108
|
+
const channelId = requireSlackConversationId(
|
|
1109
|
+
input.channelId,
|
|
1110
|
+
"Slack message deletion"
|
|
1111
|
+
);
|
|
1112
|
+
const timestamp = requireSlackMessageTimestamp(
|
|
1113
|
+
input.timestamp,
|
|
1114
|
+
"Slack message deletion"
|
|
1115
|
+
);
|
|
1116
|
+
await withSlackRetries(
|
|
1117
|
+
() => getSlackClient().chat.delete({
|
|
1118
|
+
channel: channelId,
|
|
1119
|
+
ts: timestamp
|
|
1120
|
+
}),
|
|
1121
|
+
3,
|
|
1122
|
+
{ action: "chat.delete" }
|
|
1123
|
+
);
|
|
1124
|
+
}
|
|
1103
1125
|
async function postSlackEphemeralMessage(input) {
|
|
1104
1126
|
const channelId = requireSlackConversationId(
|
|
1105
1127
|
input.channelId,
|
|
@@ -3212,6 +3234,9 @@ function appendSlackSuffix(text, marker) {
|
|
|
3212
3234
|
const carryover = getFenceContinuation(text);
|
|
3213
3235
|
return `${text}${carryover?.closeSuffix ?? ""}${marker}`;
|
|
3214
3236
|
}
|
|
3237
|
+
function stripTrailingContinuationMarker(text) {
|
|
3238
|
+
return text.endsWith(CONTINUED_MARKER) ? text.slice(0, -CONTINUED_MARKER.length) : text;
|
|
3239
|
+
}
|
|
3215
3240
|
function takeSlackContinuationChunk(text, budget) {
|
|
3216
3241
|
let { prefix, rest } = takeSlackInlinePrefix(text, budget);
|
|
3217
3242
|
if (!rest) {
|
|
@@ -3309,6 +3334,9 @@ function splitSlackReplyText(text, options) {
|
|
|
3309
3334
|
chunks.push(renderedPrefix);
|
|
3310
3335
|
remaining = rest;
|
|
3311
3336
|
}
|
|
3337
|
+
if (chunks.length === 2) {
|
|
3338
|
+
chunks[0] = stripTrailingContinuationMarker(chunks[0] ?? "");
|
|
3339
|
+
}
|
|
3312
3340
|
return chunks;
|
|
3313
3341
|
}
|
|
3314
3342
|
function getSlackContinuationBudget() {
|
|
@@ -9762,8 +9790,10 @@ function buildTurnResult(input) {
|
|
|
9762
9790
|
toolCalls,
|
|
9763
9791
|
sandboxId,
|
|
9764
9792
|
sandboxDependencyProfileHash,
|
|
9793
|
+
durationMs,
|
|
9765
9794
|
shouldTrace,
|
|
9766
9795
|
spanContext,
|
|
9796
|
+
usage,
|
|
9767
9797
|
correlation,
|
|
9768
9798
|
assistantUserName
|
|
9769
9799
|
} = input;
|
|
@@ -9838,6 +9868,8 @@ function buildTurnResult(input) {
|
|
|
9838
9868
|
toolResultCount: toolResults.length,
|
|
9839
9869
|
toolErrorCount,
|
|
9840
9870
|
usedPrimaryText,
|
|
9871
|
+
durationMs,
|
|
9872
|
+
usage,
|
|
9841
9873
|
stopReason,
|
|
9842
9874
|
errorMessage,
|
|
9843
9875
|
providerError: void 0
|
|
@@ -10156,6 +10188,7 @@ function mcpToolsToDefinitions(mcpTools) {
|
|
|
10156
10188
|
return defs;
|
|
10157
10189
|
}
|
|
10158
10190
|
async function generateAssistantReply(messageText, context = {}) {
|
|
10191
|
+
const replyStartedAtMs = Date.now();
|
|
10159
10192
|
let timeoutResumeConversationId;
|
|
10160
10193
|
let timeoutResumeSessionId;
|
|
10161
10194
|
let timeoutResumeSliceId = 1;
|
|
@@ -10166,6 +10199,7 @@ async function generateAssistantReply(messageText, context = {}) {
|
|
|
10166
10199
|
let mcpToolManager;
|
|
10167
10200
|
let sandboxExecutor;
|
|
10168
10201
|
let timedOut = false;
|
|
10202
|
+
let turnUsage;
|
|
10169
10203
|
const getSandboxMetadata = () => sandboxExecutor ? {
|
|
10170
10204
|
sandboxId: sandboxExecutor.getSandboxId(),
|
|
10171
10205
|
sandboxDependencyProfileHash: sandboxExecutor.getDependencyProfileHash()
|
|
@@ -10684,14 +10718,16 @@ async function generateAssistantReply(messageText, context = {}) {
|
|
|
10684
10718
|
}
|
|
10685
10719
|
const outputMessages = newMessages.filter(isAssistantMessage);
|
|
10686
10720
|
const outputMessagesAttribute = serializeGenAiAttribute(outputMessages);
|
|
10687
|
-
const
|
|
10721
|
+
const usageSummary = extractGenAiUsageSummary(
|
|
10688
10722
|
promptResult,
|
|
10689
10723
|
agent.state,
|
|
10690
10724
|
...outputMessages
|
|
10691
10725
|
);
|
|
10726
|
+
turnUsage = usageSummary.inputTokens !== void 0 || usageSummary.outputTokens !== void 0 || usageSummary.totalTokens !== void 0 ? usageSummary : void 0;
|
|
10692
10727
|
setSpanAttributes({
|
|
10693
10728
|
...outputMessagesAttribute ? { "gen_ai.output.messages": outputMessagesAttribute } : {},
|
|
10694
|
-
...
|
|
10729
|
+
...usageSummary.inputTokens !== void 0 ? { "gen_ai.usage.input_tokens": usageSummary.inputTokens } : {},
|
|
10730
|
+
...usageSummary.outputTokens !== void 0 ? { "gen_ai.usage.output_tokens": usageSummary.outputTokens } : {}
|
|
10695
10731
|
});
|
|
10696
10732
|
},
|
|
10697
10733
|
{
|
|
@@ -10724,9 +10760,11 @@ async function generateAssistantReply(messageText, context = {}) {
|
|
|
10724
10760
|
toolCalls,
|
|
10725
10761
|
sandboxId: currentSandboxExecutor.getSandboxId(),
|
|
10726
10762
|
sandboxDependencyProfileHash: currentSandboxExecutor.getDependencyProfileHash(),
|
|
10763
|
+
durationMs: Date.now() - replyStartedAtMs,
|
|
10727
10764
|
generatedFileCount: generatedFiles.length,
|
|
10728
10765
|
shouldTrace,
|
|
10729
10766
|
spanContext,
|
|
10767
|
+
usage: turnUsage,
|
|
10730
10768
|
correlation: context.correlation,
|
|
10731
10769
|
assistantUserName: context.assistant?.userName
|
|
10732
10770
|
});
|
|
@@ -10817,6 +10855,7 @@ async function generateAssistantReply(messageText, context = {}) {
|
|
|
10817
10855
|
toolResultCount: 0,
|
|
10818
10856
|
toolErrorCount: 0,
|
|
10819
10857
|
usedPrimaryText: false,
|
|
10858
|
+
durationMs: Date.now() - replyStartedAtMs,
|
|
10820
10859
|
errorMessage: message,
|
|
10821
10860
|
providerError: error
|
|
10822
10861
|
}
|
|
@@ -10837,6 +10876,86 @@ async function generateAssistantReply(messageText, context = {}) {
|
|
|
10837
10876
|
}
|
|
10838
10877
|
}
|
|
10839
10878
|
|
|
10879
|
+
// src/chat/slack/footer.ts
|
|
10880
|
+
function escapeSlackMrkdwn(text) {
|
|
10881
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
10882
|
+
}
|
|
10883
|
+
function formatSlackTokenCount(value) {
|
|
10884
|
+
return new Intl.NumberFormat("en-US").format(value);
|
|
10885
|
+
}
|
|
10886
|
+
function formatSlackDuration(durationMs) {
|
|
10887
|
+
if (durationMs < 1e3) {
|
|
10888
|
+
return `${durationMs}ms`;
|
|
10889
|
+
}
|
|
10890
|
+
const durationSeconds = durationMs / 1e3;
|
|
10891
|
+
if (durationSeconds < 10) {
|
|
10892
|
+
return `${durationSeconds.toFixed(1).replace(/\.0$/, "")}s`;
|
|
10893
|
+
}
|
|
10894
|
+
return `${Math.round(durationSeconds)}s`;
|
|
10895
|
+
}
|
|
10896
|
+
function resolveTotalTokens(usage) {
|
|
10897
|
+
if (usage?.totalTokens !== void 0) {
|
|
10898
|
+
return usage.totalTokens;
|
|
10899
|
+
}
|
|
10900
|
+
if (usage?.inputTokens !== void 0 && usage.outputTokens !== void 0) {
|
|
10901
|
+
return usage.inputTokens + usage.outputTokens;
|
|
10902
|
+
}
|
|
10903
|
+
return void 0;
|
|
10904
|
+
}
|
|
10905
|
+
function buildSlackReplyFooter(args) {
|
|
10906
|
+
const items = [];
|
|
10907
|
+
const conversationId = args.conversationId?.trim();
|
|
10908
|
+
if (conversationId) {
|
|
10909
|
+
items.push({
|
|
10910
|
+
label: "ID",
|
|
10911
|
+
value: conversationId
|
|
10912
|
+
});
|
|
10913
|
+
}
|
|
10914
|
+
const totalTokens = resolveTotalTokens(args.usage);
|
|
10915
|
+
if (totalTokens !== void 0) {
|
|
10916
|
+
items.push({
|
|
10917
|
+
label: "Tokens",
|
|
10918
|
+
value: formatSlackTokenCount(totalTokens)
|
|
10919
|
+
});
|
|
10920
|
+
}
|
|
10921
|
+
if (typeof args.durationMs === "number" && Number.isFinite(args.durationMs)) {
|
|
10922
|
+
const durationMs = Math.max(0, Math.floor(args.durationMs));
|
|
10923
|
+
items.push({
|
|
10924
|
+
label: "Time",
|
|
10925
|
+
value: formatSlackDuration(durationMs)
|
|
10926
|
+
});
|
|
10927
|
+
}
|
|
10928
|
+
const traceId = args.traceId?.trim();
|
|
10929
|
+
if (traceId) {
|
|
10930
|
+
items.push({
|
|
10931
|
+
label: "Trace",
|
|
10932
|
+
value: traceId
|
|
10933
|
+
});
|
|
10934
|
+
}
|
|
10935
|
+
return items.length > 0 ? { items } : void 0;
|
|
10936
|
+
}
|
|
10937
|
+
function buildSlackReplyBlocks(text, footer) {
|
|
10938
|
+
if (!text.trim() || !footer?.items.length) {
|
|
10939
|
+
return void 0;
|
|
10940
|
+
}
|
|
10941
|
+
return [
|
|
10942
|
+
{
|
|
10943
|
+
type: "section",
|
|
10944
|
+
text: {
|
|
10945
|
+
type: "mrkdwn",
|
|
10946
|
+
text
|
|
10947
|
+
}
|
|
10948
|
+
},
|
|
10949
|
+
{
|
|
10950
|
+
type: "context",
|
|
10951
|
+
elements: footer.items.map((item) => ({
|
|
10952
|
+
type: "mrkdwn",
|
|
10953
|
+
text: `*${escapeSlackMrkdwn(item.label)}:* ${escapeSlackMrkdwn(item.value)}`
|
|
10954
|
+
}))
|
|
10955
|
+
}
|
|
10956
|
+
];
|
|
10957
|
+
}
|
|
10958
|
+
|
|
10840
10959
|
// src/chat/slack/reply.ts
|
|
10841
10960
|
import { Buffer as Buffer2 } from "buffer";
|
|
10842
10961
|
function isInterruptedVisibleReply(reply) {
|
|
@@ -10892,14 +11011,25 @@ async function normalizeFileUploads(files) {
|
|
|
10892
11011
|
})
|
|
10893
11012
|
);
|
|
10894
11013
|
}
|
|
10895
|
-
|
|
11014
|
+
function findLastTextPostIndex(posts) {
|
|
11015
|
+
for (let index = posts.length - 1; index >= 0; index -= 1) {
|
|
11016
|
+
if (posts[index]?.text.trim().length) {
|
|
11017
|
+
return index;
|
|
11018
|
+
}
|
|
11019
|
+
}
|
|
11020
|
+
return -1;
|
|
11021
|
+
}
|
|
11022
|
+
async function uploadReplyFiles(args) {
|
|
10896
11023
|
try {
|
|
10897
11024
|
await uploadFilesToThread({
|
|
10898
11025
|
channelId: args.channelId,
|
|
10899
11026
|
threadTs: args.threadTs,
|
|
10900
11027
|
files: await normalizeFileUploads(args.files)
|
|
10901
11028
|
});
|
|
10902
|
-
} catch {
|
|
11029
|
+
} catch (error) {
|
|
11030
|
+
if (args.failureMode === "strict") {
|
|
11031
|
+
throw error;
|
|
11032
|
+
}
|
|
10903
11033
|
}
|
|
10904
11034
|
}
|
|
10905
11035
|
function planSlackReplyPosts(args) {
|
|
@@ -10937,19 +11067,44 @@ function planSlackReplyPosts(args) {
|
|
|
10937
11067
|
return posts;
|
|
10938
11068
|
}
|
|
10939
11069
|
async function postSlackApiReplyPosts(args) {
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
if (
|
|
10945
|
-
|
|
11070
|
+
const lastTextPostIndex = findLastTextPostIndex(args.posts);
|
|
11071
|
+
let lastPostedMessageTs;
|
|
11072
|
+
for (const [index, post] of args.posts.entries()) {
|
|
11073
|
+
const hasVisibleDelivery = post.text.trim().length > 0 || post.files?.length;
|
|
11074
|
+
if (hasVisibleDelivery) {
|
|
11075
|
+
await args.beforePost?.();
|
|
11076
|
+
}
|
|
11077
|
+
let messageTs;
|
|
11078
|
+
try {
|
|
11079
|
+
if (post.text.trim().length > 0) {
|
|
11080
|
+
const response = await postSlackMessage({
|
|
11081
|
+
channelId: args.channelId,
|
|
11082
|
+
threadTs: args.threadTs,
|
|
11083
|
+
text: post.text,
|
|
11084
|
+
...index === lastTextPostIndex && args.footer ? { blocks: buildSlackReplyBlocks(post.text, args.footer) } : {}
|
|
11085
|
+
});
|
|
11086
|
+
messageTs = response.ts;
|
|
11087
|
+
lastPostedMessageTs = response.ts;
|
|
11088
|
+
}
|
|
11089
|
+
if (!post.files?.length) {
|
|
11090
|
+
continue;
|
|
11091
|
+
}
|
|
11092
|
+
await uploadReplyFiles({
|
|
11093
|
+
channelId: args.channelId,
|
|
11094
|
+
failureMode: args.fileUploadFailureMode ?? "best_effort",
|
|
11095
|
+
threadTs: args.threadTs,
|
|
11096
|
+
files: post.files
|
|
11097
|
+
});
|
|
11098
|
+
} catch (error) {
|
|
11099
|
+
await args.onPostError?.({
|
|
11100
|
+
error,
|
|
11101
|
+
messageTs,
|
|
11102
|
+
stage: post.stage
|
|
11103
|
+
});
|
|
11104
|
+
throw error;
|
|
10946
11105
|
}
|
|
10947
|
-
await uploadReplyFilesBestEffort({
|
|
10948
|
-
channelId: args.channelId,
|
|
10949
|
-
threadTs: args.threadTs,
|
|
10950
|
-
files: post.files
|
|
10951
|
-
});
|
|
10952
11106
|
}
|
|
11107
|
+
return lastPostedMessageTs;
|
|
10953
11108
|
}
|
|
10954
11109
|
|
|
10955
11110
|
// src/chat/slack/resume.ts
|
|
@@ -10964,16 +11119,13 @@ function resolveReplyTimeoutMs(explicitTimeoutMs) {
|
|
|
10964
11119
|
const parsed = Number.parseInt(raw, 10);
|
|
10965
11120
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
10966
11121
|
}
|
|
10967
|
-
async function postSlackMessage2(channelId, threadTs, text) {
|
|
10968
|
-
await postSlackMessage({
|
|
10969
|
-
channelId,
|
|
10970
|
-
threadTs,
|
|
10971
|
-
text
|
|
10972
|
-
});
|
|
10973
|
-
}
|
|
10974
11122
|
async function postSlackMessageBestEffort(channelId, threadTs, text) {
|
|
10975
11123
|
try {
|
|
10976
|
-
await
|
|
11124
|
+
await postSlackMessage({
|
|
11125
|
+
channelId,
|
|
11126
|
+
threadTs,
|
|
11127
|
+
text
|
|
11128
|
+
});
|
|
10977
11129
|
} catch {
|
|
10978
11130
|
}
|
|
10979
11131
|
}
|
|
@@ -11097,11 +11249,18 @@ async function resumeSlackTurn(args) {
|
|
|
11097
11249
|
)
|
|
11098
11250
|
]) : await replyPromise;
|
|
11099
11251
|
await status.stop();
|
|
11252
|
+
const footer = buildSlackReplyFooter({
|
|
11253
|
+
conversationId: args.replyContext?.correlation?.conversationId ?? lockKey,
|
|
11254
|
+
durationMs: reply.diagnostics.durationMs,
|
|
11255
|
+
traceId: getActiveTraceId(),
|
|
11256
|
+
usage: reply.diagnostics.usage
|
|
11257
|
+
});
|
|
11100
11258
|
await postSlackApiReplyPosts({
|
|
11101
11259
|
channelId: args.channelId,
|
|
11102
11260
|
threadTs: args.threadTs,
|
|
11103
11261
|
posts: planSlackReplyPosts({ reply }),
|
|
11104
|
-
|
|
11262
|
+
fileUploadFailureMode: "best_effort",
|
|
11263
|
+
footer
|
|
11105
11264
|
});
|
|
11106
11265
|
await args.onSuccess?.(reply);
|
|
11107
11266
|
} catch (error) {
|
|
@@ -11903,11 +12062,11 @@ async function GET5(request, provider, waitUntil) {
|
|
|
11903
12062
|
} else if (stored.channelId && stored.threadTs) {
|
|
11904
12063
|
const { channelId, threadTs } = stored;
|
|
11905
12064
|
waitUntil(
|
|
11906
|
-
() =>
|
|
12065
|
+
() => postSlackMessage({
|
|
11907
12066
|
channelId,
|
|
11908
12067
|
threadTs,
|
|
11909
|
-
`Your ${providerLabel} account is now connected. You can start using ${providerLabel} commands.`
|
|
11910
|
-
)
|
|
12068
|
+
text: `Your ${providerLabel} account is now connected. You can start using ${providerLabel} commands.`
|
|
12069
|
+
})
|
|
11911
12070
|
);
|
|
11912
12071
|
}
|
|
11913
12072
|
const statusMessage = stored.pendingMessage ? "Your request is being processed in Slack." : "You can close this tab and return to Slack.";
|
|
@@ -12553,11 +12712,20 @@ function getAssistantThreadContext(message) {
|
|
|
12553
12712
|
const raw = message.raw;
|
|
12554
12713
|
const rawRecord = raw && typeof raw === "object" ? raw : void 0;
|
|
12555
12714
|
const channelId = toOptionalString(rawRecord?.channel);
|
|
12556
|
-
|
|
12557
|
-
|
|
12715
|
+
if (channelId) {
|
|
12716
|
+
const rawThreadTs = toOptionalString(rawRecord?.thread_ts);
|
|
12717
|
+
const threadTs = isDmChannel(channelId) ? rawThreadTs : rawThreadTs ?? toOptionalString(rawRecord?.ts);
|
|
12718
|
+
if (threadTs) {
|
|
12719
|
+
return { channelId, threadTs };
|
|
12720
|
+
}
|
|
12721
|
+
}
|
|
12722
|
+
const parsedThreadId = parseSlackThreadId(
|
|
12723
|
+
toOptionalString(message.threadId)
|
|
12724
|
+
);
|
|
12725
|
+
if (!parsedThreadId || isDmChannel(parsedThreadId.channelId)) {
|
|
12558
12726
|
return void 0;
|
|
12559
12727
|
}
|
|
12560
|
-
return
|
|
12728
|
+
return parsedThreadId;
|
|
12561
12729
|
}
|
|
12562
12730
|
function getMessageTs(message) {
|
|
12563
12731
|
const directTs = toOptionalString(
|
|
@@ -13948,13 +14116,63 @@ function createReplyToThread(deps) {
|
|
|
13948
14116
|
"slackMessageAddReaction"
|
|
13949
14117
|
);
|
|
13950
14118
|
const plannedPosts = planSlackReplyPosts({ reply });
|
|
14119
|
+
const replyFooter = buildSlackReplyFooter({
|
|
14120
|
+
conversationId,
|
|
14121
|
+
durationMs: reply.diagnostics.durationMs,
|
|
14122
|
+
traceId: getActiveTraceId(),
|
|
14123
|
+
usage: reply.diagnostics.usage
|
|
14124
|
+
});
|
|
14125
|
+
const shouldUseSlackFooter = Boolean(replyFooter) && Boolean(channelId && threadTs) && thread.adapter?.name === "slack";
|
|
13951
14126
|
if (plannedPosts.length > 0) {
|
|
13952
14127
|
let sent;
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
14128
|
+
if (shouldUseSlackFooter) {
|
|
14129
|
+
const slackChannelId = channelId;
|
|
14130
|
+
const slackThreadTs = threadTs;
|
|
14131
|
+
if (!slackChannelId || !slackThreadTs) {
|
|
14132
|
+
throw new Error(
|
|
14133
|
+
"Slack footer delivery requires a concrete channel and thread timestamp"
|
|
14134
|
+
);
|
|
14135
|
+
}
|
|
14136
|
+
const sentMessageTs = await postSlackApiReplyPosts({
|
|
14137
|
+
beforePost: beforeFirstResponsePost,
|
|
14138
|
+
channelId: slackChannelId,
|
|
14139
|
+
threadTs: slackThreadTs,
|
|
14140
|
+
posts: plannedPosts,
|
|
14141
|
+
fileUploadFailureMode: "strict",
|
|
14142
|
+
footer: replyFooter,
|
|
14143
|
+
onPostError: ({ error, messageTs: messageTs2, stage }) => {
|
|
14144
|
+
logException(
|
|
14145
|
+
error,
|
|
14146
|
+
"slack_thread_post_failed",
|
|
14147
|
+
turnTraceContext,
|
|
14148
|
+
{
|
|
14149
|
+
"app.slack.reply_stage": stage,
|
|
14150
|
+
...messageTs2 ? { "messaging.message.id": messageTs2 } : {},
|
|
14151
|
+
...getSlackErrorObservabilityAttributes(error)
|
|
14152
|
+
},
|
|
14153
|
+
"Failed to post Slack thread reply"
|
|
14154
|
+
);
|
|
14155
|
+
}
|
|
14156
|
+
});
|
|
14157
|
+
if (sentMessageTs) {
|
|
14158
|
+
sent = {
|
|
14159
|
+
id: sentMessageTs,
|
|
14160
|
+
text: reply.text,
|
|
14161
|
+
delete: async () => {
|
|
14162
|
+
await deleteSlackMessage({
|
|
14163
|
+
channelId: slackChannelId,
|
|
14164
|
+
timestamp: sentMessageTs
|
|
14165
|
+
});
|
|
14166
|
+
}
|
|
14167
|
+
};
|
|
14168
|
+
}
|
|
14169
|
+
} else {
|
|
14170
|
+
for (const post of plannedPosts) {
|
|
14171
|
+
sent = await postThreadReply(
|
|
14172
|
+
buildSlackOutputMessage(post.text, post.files),
|
|
14173
|
+
post.stage
|
|
14174
|
+
);
|
|
14175
|
+
}
|
|
13958
14176
|
}
|
|
13959
14177
|
const firstPlannedMessageHasFiles = (plannedPosts[0]?.files?.length ?? 0) > 0;
|
|
13960
14178
|
if (sent && reactionPerformed && plannedPosts.length === 1 && !firstPlannedMessageHasFiles && isRedundantReactionAckText(reply.text)) {
|
|
@@ -1236,7 +1236,7 @@ function collectUsageRoots(source) {
|
|
|
1236
1236
|
}
|
|
1237
1237
|
return roots;
|
|
1238
1238
|
}
|
|
1239
|
-
function
|
|
1239
|
+
function extractGenAiUsageSummary(...sources) {
|
|
1240
1240
|
const roots = sources.flatMap((source) => collectUsageRoots(source));
|
|
1241
1241
|
if (roots.length === 0) {
|
|
1242
1242
|
return {};
|
|
@@ -1261,6 +1261,21 @@ function extractGenAiUsageAttributes(...sources) {
|
|
|
1261
1261
|
"completionTokenCount"
|
|
1262
1262
|
])
|
|
1263
1263
|
).find((value) => value !== void 0) ?? void 0;
|
|
1264
|
+
const totalTokens = roots.map(
|
|
1265
|
+
(root) => readTokenCount(root, [
|
|
1266
|
+
"total_tokens",
|
|
1267
|
+
"totalTokens",
|
|
1268
|
+
"totalTokenCount"
|
|
1269
|
+
])
|
|
1270
|
+
).find((value) => value !== void 0) ?? void 0;
|
|
1271
|
+
return {
|
|
1272
|
+
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1273
|
+
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1274
|
+
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
function extractGenAiUsageAttributes(...sources) {
|
|
1278
|
+
const { inputTokens, outputTokens } = extractGenAiUsageSummary(...sources);
|
|
1264
1279
|
return {
|
|
1265
1280
|
...inputTokens !== void 0 ? { "gen_ai.usage.input_tokens": inputTokens } : {},
|
|
1266
1281
|
...outputTokens !== void 0 ? { "gen_ai.usage.output_tokens": outputTokens } : {}
|
|
@@ -2789,6 +2804,7 @@ export {
|
|
|
2789
2804
|
getActiveTraceId,
|
|
2790
2805
|
resolveErrorReference,
|
|
2791
2806
|
serializeGenAiAttribute,
|
|
2807
|
+
extractGenAiUsageSummary,
|
|
2792
2808
|
extractGenAiUsageAttributes,
|
|
2793
2809
|
resolveAuthTokenPlaceholder,
|
|
2794
2810
|
parsePluginManifest,
|
package/dist/cli/check.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSkillFile
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-O5N42P7K.js";
|
|
4
4
|
import {
|
|
5
5
|
parsePluginManifest
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-I3WA75AD.js";
|
|
7
7
|
import "../chunk-Z3YD6NHK.js";
|
|
8
8
|
import "../chunk-XPXD3FCE.js";
|
|
9
9
|
import "../chunk-2KG3PWR4.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
disconnectStateAdapter,
|
|
3
3
|
resolveRuntimeDependencySnapshot
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-RMVXZMXQ.js";
|
|
5
5
|
import {
|
|
6
6
|
getPluginProviders,
|
|
7
7
|
getPluginRuntimeDependencies,
|
|
8
8
|
getPluginRuntimePostinstall
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-I3WA75AD.js";
|
|
10
10
|
import "../chunk-Z3YD6NHK.js";
|
|
11
11
|
import "../chunk-XPXD3FCE.js";
|
|
12
12
|
import "../chunk-2KG3PWR4.js";
|