Skip to content

Commit 9dbb0f7

Browse files
sentry-junior[bot]codexdcramer
authored
feat(slack): show thinking level in reply footer (#240)
Show the per-turn thinking level in the finalized Slack reply footer instead of the active trace ID, and carry that footer through both normal reply execution and resumed reply delivery. The footer is a user-visible artifact, so the selected reasoning bucket is more useful than an internal tracing identifier. This update also tightens the footer helper to the existing thinking-level contract and aligns the Slack footer specs with the metadata we actually render. I considered leaving the stale trace-oriented assertions and broader footer input in place, but that would keep the tests and public contract looser than the intended behavior. The follow-up test changes here are narrowly scoped to environment and module-state isolation around the touched suites. --------- Co-authored-by: OpenAI Codex <codex@openai.com> Co-authored-by: David Cramer <dcramer@gmail.com> Co-authored-by: GPT-5 <noreply@openai.com>
1 parent cb40f66 commit 9dbb0f7

12 files changed

Lines changed: 41 additions & 34 deletions

packages/junior/src/chat/runtime/reply-executor.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { SlackAdapter } from "@chat-adapter/slack";
33
import { botConfig } from "@/chat/config";
44
import { getSlackMessageTs } from "@/chat/slack/message";
55
import {
6-
getActiveTraceId,
76
logException,
87
logInfo,
98
logWarn,
@@ -447,7 +446,7 @@ export function createReplyToThread(deps: ReplyExecutorDeps) {
447446
const replyFooter = buildSlackReplyFooter({
448447
conversationId,
449448
durationMs: reply.diagnostics.durationMs,
450-
traceId: getActiveTraceId(),
449+
thinkingLevel: reply.diagnostics.thinkingLevel,
451450
usage: reply.diagnostics.usage,
452451
});
453452
const shouldUseSlackFooter =

packages/junior/src/chat/slack/footer.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { TurnThinkingSelection } from "@/chat/services/turn-thinking-level";
12
import type { AgentTurnUsage } from "@/chat/usage";
23

34
interface SlackMrkdwnTextObject {
@@ -17,7 +18,7 @@ interface SlackContextBlock {
1718

1819
export type SlackMessageBlock = SlackSectionBlock | SlackContextBlock;
1920

20-
export interface SlackReplyFooterItem {
21+
interface SlackReplyFooterItem {
2122
label: string;
2223
value: string;
2324
}
@@ -83,7 +84,7 @@ function resolveTotalTokens(
8384
export function buildSlackReplyFooter(args: {
8485
conversationId?: string;
8586
durationMs?: number;
86-
traceId?: string;
87+
thinkingLevel?: TurnThinkingSelection["thinkingLevel"];
8788
usage?: AgentTurnUsage;
8889
}): SlackReplyFooter | undefined {
8990
const items: SlackReplyFooterItem[] = [];
@@ -112,11 +113,10 @@ export function buildSlackReplyFooter(args: {
112113
});
113114
}
114115

115-
const traceId = args.traceId?.trim();
116-
if (traceId) {
116+
if (args.thinkingLevel) {
117117
items.push({
118-
label: "Trace",
119-
value: traceId,
118+
label: "Thinking",
119+
value: args.thinkingLevel,
120120
});
121121
}
122122

packages/junior/src/chat/slack/resume.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { botConfig } from "@/chat/config";
22
import type { ChannelConfigurationService } from "@/chat/configuration/types";
3-
import { getActiveTraceId } from "@/chat/logging";
43
import {
54
generateAssistantReply,
65
type AssistantReply,
@@ -226,7 +225,7 @@ export async function resumeSlackTurn(args: ResumeSlackTurnArgs) {
226225
const footer = buildSlackReplyFooter({
227226
conversationId: args.replyContext?.correlation?.conversationId ?? lockKey,
228227
durationMs: reply.diagnostics.durationMs,
229-
traceId: getActiveTraceId(),
228+
thinkingLevel: reply.diagnostics.thinkingLevel,
230229
usage: reply.diagnostics.usage,
231230
});
232231
await postSlackApiReplyPosts({

packages/junior/tests/integration/example-build-discovery.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ function getExamplePluginPackages(): string[] {
2525
function buildJuniorPackage(): void {
2626
const env: NodeJS.ProcessEnv = {
2727
...process.env,
28+
CI: "true",
2829
JUNIOR_SKIP_SNAPSHOT: "1",
2930
};
3031
delete env.JUNIOR_EXTRA_PLUGIN_ROOTS;

packages/junior/tests/integration/slack/attachment-media-behavior.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ async function createRuntime(
1515
) {
1616
process.env = {
1717
...ORIGINAL_ENV,
18+
AI_VISION_MODEL: "",
1819
SLACK_BOT_TOKEN: "",
1920
SLACK_BOT_USER_TOKEN: "",
2021
...env,

packages/junior/tests/integration/slack/bot-image-hydration.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async function createRuntime(
1616
) {
1717
process.env = {
1818
...ORIGINAL_ENV,
19+
AI_VISION_MODEL: "",
1920
SLACK_BOT_TOKEN: "",
2021
SLACK_BOT_USER_TOKEN: "",
2122
...env,

packages/junior/tests/integration/slack/message-changed-reply-contract.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,6 @@ describe("Slack contract: edited-message reply delivery", () => {
165165
"*ID:* slack:D12345:1700000100.000100",
166166
),
167167
}),
168-
expect.objectContaining({
169-
type: "mrkdwn",
170-
text: expect.stringContaining("*Trace:* "),
171-
}),
172168
]),
173169
},
174170
],

packages/junior/tests/integration/slack/outbound-normalization-contract.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe("Slack contract: outbound normalization", () => {
4444
it("passes block payloads with a top-level fallback text", async () => {
4545
const footer = buildSlackReplyFooter({
4646
conversationId: "slack:C123:1700000000.000100",
47-
traceId: "trace_123",
47+
thinkingLevel: "low",
4848
});
4949

5050
await postSlackMessage({
@@ -75,7 +75,7 @@ describe("Slack contract: outbound normalization", () => {
7575
},
7676
{
7777
type: "mrkdwn",
78-
text: "*Trace:* trace_123",
78+
text: "*Thinking:* low",
7979
},
8080
],
8181
},

packages/junior/tests/unit/services/turn-checkpoint.test.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
1-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
1+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
22
import type { AgentMessage } from "@mariozechner/pi-agent-core";
3-
import { persistAuthPauseCheckpoint } from "@/chat/services/turn-checkpoint";
4-
import { disconnectStateAdapter } from "@/chat/state/adapter";
5-
import {
6-
getAgentTurnSessionCheckpoint,
7-
upsertAgentTurnSessionCheckpoint,
8-
} from "@/chat/state/turn-session-store";
3+
4+
const ORIGINAL_ENV = { ...process.env };
95

106
describe("persistAuthPauseCheckpoint", () => {
117
beforeEach(async () => {
12-
process.env.JUNIOR_STATE_ADAPTER = "memory";
8+
process.env = {
9+
...ORIGINAL_ENV,
10+
JUNIOR_STATE_ADAPTER: "memory",
11+
};
12+
vi.resetModules();
13+
const { disconnectStateAdapter } = await import("@/chat/state/adapter");
1314
await disconnectStateAdapter();
1415
});
1516

1617
afterEach(async () => {
18+
const { disconnectStateAdapter } = await import("@/chat/state/adapter");
1719
await disconnectStateAdapter();
18-
delete process.env.JUNIOR_STATE_ADAPTER;
20+
vi.resetModules();
21+
process.env = { ...ORIGINAL_ENV };
1922
});
2023

2124
it("reuses the latest stored transcript when the auth pause captured no messages", async () => {
25+
const { persistAuthPauseCheckpoint } =
26+
await import("@/chat/services/turn-checkpoint");
27+
const { getAgentTurnSessionCheckpoint, upsertAgentTurnSessionCheckpoint } =
28+
await import("@/chat/state/turn-session-store");
29+
2230
const priorMessages: AgentMessage[] = [
2331
{
2432
role: "user",

packages/junior/tests/unit/slack/footer.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe("buildSlackReplyFooter", () => {
1010
buildSlackReplyFooter({
1111
conversationId: "slack:C123:1700000000.000100",
1212
durationMs: 842,
13-
traceId: "0123456789abcdef0123456789abcdef",
13+
thinkingLevel: "medium",
1414
usage: {
1515
totalTokens: 1234,
1616
},
@@ -30,8 +30,8 @@ describe("buildSlackReplyFooter", () => {
3030
value: "842ms",
3131
},
3232
{
33-
label: "Trace",
34-
value: "0123456789abcdef0123456789abcdef",
33+
label: "Thinking",
34+
value: "medium",
3535
},
3636
],
3737
});
@@ -83,7 +83,7 @@ describe("buildSlackReplyBlocks", () => {
8383
const footer = buildSlackReplyFooter({
8484
conversationId: "slack:C123:1700000000.000100",
8585
durationMs: 1250,
86-
traceId: "trace_123",
86+
thinkingLevel: "high",
8787
usage: {
8888
inputTokens: 400,
8989
outputTokens: 250,
@@ -115,7 +115,7 @@ describe("buildSlackReplyBlocks", () => {
115115
},
116116
{
117117
type: "mrkdwn",
118-
text: "*Trace:* trace_123",
118+
text: "*Thinking:* high",
119119
},
120120
],
121121
},

0 commit comments

Comments
 (0)