Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
"@sentry/junior-linear": "workspace:*",
"@sentry/junior-notion": "workspace:*",
"@sentry/junior-sentry": "workspace:*",
"@sentry/node": "^10.48.0",
"hono": "^4.12.14"
"@sentry/node": "^10.51.0",
"hono": "^4.12.18"
},
"devDependencies": {
"@types/node": "^25.6.0",
"jiti": "^2.6.1",
"nitro": "3.0.260415-beta",
"jiti": "^2.7.0",
"nitro": "3.0.260429-beta",
"typescript": "^5.9.3"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
}
},
"devDependencies": {
"agent-browser": "^0.23.3",
"agent-browser": "^0.26.0",
"lint-staged": "^16.4.0",
"prettier": "^3.8.3",
"simple-git-hooks": "^2.13.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"check": "astro check && astro build"
},
"dependencies": {
"@astrojs/check": "^0.9.8",
"@astrojs/check": "^0.9.9",
"@astrojs/starlight": "^0.37.7",
"@fontsource-variable/space-grotesk": "^5.2.10",
"@fontsource/ibm-plex-mono": "^5.2.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "POST"

> **POST**(`request`, `platform`, `waitUntil`): `Promise`\<`Response`\>

Defined in: [handlers/webhooks.ts:238](https://github.com/getsentry/junior/blob/main/packages/junior/src/handlers/webhooks.ts#L238)
Defined in: [handlers/webhooks.ts:252](https://github.com/getsentry/junior/blob/main/packages/junior/src/handlers/webhooks.ts#L252)

## Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "handlePlatformWebhook"

> **handlePlatformWebhook**(`request`, `platform`, `waitUntil`, `bot?`): `Promise`\<`Response`\>

Defined in: [handlers/webhooks.ts:119](https://github.com/getsentry/junior/blob/main/packages/junior/src/handlers/webhooks.ts#L119)
Defined in: [handlers/webhooks.ts:124](https://github.com/getsentry/junior/blob/main/packages/junior/src/handlers/webhooks.ts#L124)

Handles `POST /api/webhooks/:platform`.

Expand Down
4 changes: 2 additions & 2 deletions packages/junior-evals/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
"@sentry/junior": "workspace:*",
"@sentry/junior-github": "workspace:*",
"@sentry/junior-sentry": "workspace:*",
"chat": "4.26.0",
"chat": "4.27.0",
"typescript": "^5.9.3",
"vitest": "^4.1.4",
"vitest": "^4.1.5",
"vitest-evals": "0.9.0-beta.1"
}
}
25 changes: 22 additions & 3 deletions packages/junior-evals/tests/unit/harness/behavior-harness.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ describe("behavior harness", () => {
expect(observedRuntimeIds.messageThreadId).toBe(
"slack:C_AUTH:1700000000.0001",
);
expect(result.posts).toEqual([{ text: "observed", files: [] }]);
expect(result.posts).toEqual([
{
channel: "C_AUTH",
files: [],
text: "observed",
thread_ts: "1700000000.0001",
},
]);
});

it("routes two same-thread mention-shaped events through the queued runtime in order", async () => {
Expand Down Expand Up @@ -141,8 +148,18 @@ describe("behavior harness", () => {
expect(handleNewMentionMock).toHaveBeenCalledTimes(1);
expect(handleSubscribedMessageMock).toHaveBeenCalledTimes(1);
expect(result.posts).toEqual([
{ text: "observed", files: [] },
{ text: "observed", files: [] },
{
channel: "C_QUEUE",
files: [],
text: "observed",
thread_ts: "1700000000.0002",
},
{
channel: "C_QUEUE",
files: [],
text: "observed",
thread_ts: "1700000000.0002",
},
]);
});

Expand Down Expand Up @@ -185,7 +202,9 @@ describe("behavior harness", () => {

expect(result.posts).toEqual([
{
channel: "C_MEDIA",
text: "",
thread_ts: "1700000000.0003",
files: [
{
filename: "generated.png",
Expand Down
38 changes: 19 additions & 19 deletions packages/junior/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,40 @@
"skills:check": "node scripts/check-skills.mjs"
},
"dependencies": {
"@ai-sdk/gateway": "^3.0.99",
"@chat-adapter/slack": "4.26.0",
"@chat-adapter/state-memory": "4.26.0",
"@chat-adapter/state-redis": "4.26.0",
"@logtape/logtape": "^2.0.5",
"@ai-sdk/gateway": "^3.0.110",
"@chat-adapter/slack": "4.27.0",
"@chat-adapter/state-memory": "4.27.0",
"@chat-adapter/state-redis": "4.27.0",
"@logtape/logtape": "^2.0.7",
"@mariozechner/pi-agent-core": "0.73.0",
"@mariozechner/pi-ai": "0.73.0",
"@modelcontextprotocol/sdk": "1.29.0",
"@sinclair/typebox": "^0.34.49",
"@slack/web-api": "^7.15.1",
"@vercel/functions": "^3.4.3",
"@slack/web-api": "^7.15.2",
"@vercel/functions": "^3.5.0",
"@vercel/sandbox": "^1.10.0",
"ai": "^6.0.162",
"ai": "^6.0.175",
"bash-tool": "^1.3.16",
"chat": "4.26.0",
"hono": "^4.12.14",
"just-bash": "^2.14.2",
"chat": "4.27.0",
"hono": "^4.12.18",
"just-bash": "2.14.2",
"node-html-markdown": "^2.0.0",
"yaml": "^2.8.3",
"zod": "^4.3.6"
"yaml": "^2.8.4",
"zod": "^4.4.3"
},
"peerDependencies": {
"@sentry/node": ">=10.0.0"
},
"devDependencies": {
"@sentry/node": "^10.48.0",
"@sentry/node": "^10.51.0",
"@types/node": "^25.6.0",
"dependency-cruiser": "^17.3.10",
"msw": "^2.13.3",
"nitro": "3.0.260415-beta",
"oxlint": "^1.60.0",
"dependency-cruiser": "^17.4.0",
"msw": "^2.14.3",
"nitro": "3.0.260429-beta",
"oxlint": "^1.63.0",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"vercel": "^51.4.0",
"vitest": "^4.1.4"
"vitest": "^4.1.5"
}
}
8 changes: 6 additions & 2 deletions packages/junior/src/handlers/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { WaitUntilFn } from "@/handlers/types";

interface SlackWebhookAuthAdapter {
botUserId?: string;
defaultBotToken?: string;
defaultBotTokenProvider?: () => string | Promise<string>;
requestContext?: {
run<T>(context: unknown, fn: () => T): T;
};
Expand Down Expand Up @@ -57,6 +57,10 @@ async function handleAuthenticatedSlackMessageChangedMention(args: {
return;
}

// Chat SDK initializes adapters automatically inside webhook handling. This
// side-channel runs before the SDK handler, so it must join that lifecycle.
await args.bot.initialize();

const webhookOptions = {
waitUntil: (task: Promise<unknown>) => args.waitUntil(task),
};
Expand Down Expand Up @@ -85,7 +89,7 @@ async function handleAuthenticatedSlackMessageChangedMention(args: {
return true;
};

if (authAdapter.defaultBotToken) {
if (authAdapter.defaultBotTokenProvider) {
dispatch();
return;
}
Expand Down
3 changes: 3 additions & 0 deletions packages/junior/tests/fixtures/slack-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ export function createTestThread(args: {
createSentMessageFromMessage(message: Message): SentMessage {
return message as unknown as SentMessage;
},
async getParticipants(): Promise<Author[]> {
return [];
},
get posts() {
return posts;
},
Expand Down
33 changes: 24 additions & 9 deletions packages/junior/tests/integration/example-build-discovery.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import { cpSync, readFileSync, realpathSync, rmSync } from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
Expand All @@ -9,6 +10,15 @@ const originalCwd = process.cwd();
const repoRoot = path.resolve(import.meta.dirname, "../../../..");
const exampleRoot = path.join(repoRoot, "apps/example");
const exampleEntry = path.join(exampleRoot, "server.ts");
const exampleRequire = createRequire(exampleEntry);

function isSamePath(left: string, right: string): boolean {
try {
return realpathSync(left) === realpathSync(right);
} catch {
return false;
}
}

function getExamplePluginPackages(): string[] {
const pkg = JSON.parse(
Expand Down Expand Up @@ -37,15 +47,20 @@ function buildJuniorPackage(): void {
stdio: "pipe",
});

// Re-sync pnpm store so the example app's node_modules/@sentry/junior
// points to the freshly built dist, not a stale hardlink. The relink does
// not need workspace prepare hooks, which would rebuild @sentry/junior and
// make the full suite timeout-prone.
execFileSync("pnpm", ["install", "--ignore-scripts"], {
cwd: repoRoot,
env,
stdio: "pipe",
const installedPackageRoot = path.dirname(
path.dirname(exampleRequire.resolve("@sentry/junior")),
);
const sourceDist = path.join(repoRoot, "packages/junior/dist");
const installedDist = path.join(installedPackageRoot, "dist");
if (isSamePath(installedDist, sourceDist)) {
return;
}

rmSync(installedDist, {
force: true,
recursive: true,
});
cpSync(sourceDist, installedDist, { recursive: true });
}

async function importExampleApp() {
Expand Down
12 changes: 9 additions & 3 deletions packages/junior/tests/unit/runtime/respond-error-path.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it, vi } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";

vi.mock("@/chat/skills", () => ({
discoverSkills: vi.fn(async () => {
Expand All @@ -8,10 +8,16 @@ vi.mock("@/chat/skills", () => ({
parseSkillInvocation: vi.fn(),
}));

import { generateAssistantReply } from "@/chat/respond";

describe("generateAssistantReply error path", () => {
afterEach(() => {
vi.unstubAllEnvs();
});

it("preserves sandbox dependency hash on non-retryable failures", async () => {
vi.resetModules();
vi.stubEnv("AI_MODEL", "openai/gpt-5.4");
const { generateAssistantReply } = await import("@/chat/respond");

const reply = await generateAssistantReply("hello", {
sandbox: {
sandboxId: "sb-123",
Expand Down
Loading
Loading