@sentry/junior 0.9.4 → 0.10.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/README.md +0 -7
- package/dist/{chunk-FLP5I4NM.js → chunk-7RM2Y52T.js} +283 -589
- package/dist/{chunk-FS5Y4CF2.js → chunk-BJ4EBVQK.js} +17 -34
- package/dist/cli/init.js +21 -12
- package/dist/cli/snapshot-warmup.js +1 -1
- package/dist/handlers/router.d.ts +2 -4
- package/dist/handlers/router.js +26 -48
- package/dist/handlers/webhooks.d.ts +8 -1
- package/dist/handlers/webhooks.js +6 -5
- package/dist/next-config.js +0 -1
- package/package.json +16 -18
- package/dist/chunk-SO4ORZJR.js +0 -103
- package/dist/chunk-YGERYE7Y.js +0 -685
- package/dist/handlers/queue-callback.d.ts +0 -10
- package/dist/handlers/queue-callback.js +0 -11
|
@@ -4,10 +4,6 @@ import {
|
|
|
4
4
|
withSpan
|
|
5
5
|
} from "./chunk-MY7JNCS2.js";
|
|
6
6
|
|
|
7
|
-
// src/chat/state/adapter.ts
|
|
8
|
-
import { createMemoryState } from "@chat-adapter/state-memory";
|
|
9
|
-
import { createRedisState } from "@chat-adapter/state-redis";
|
|
10
|
-
|
|
11
7
|
// src/chat/optional-string.ts
|
|
12
8
|
function toOptionalTrimmed(value) {
|
|
13
9
|
if (!value) {
|
|
@@ -20,8 +16,8 @@ function toOptionalTrimmed(value) {
|
|
|
20
16
|
// src/chat/config.ts
|
|
21
17
|
var MIN_AGENT_TURN_TIMEOUT_MS = 10 * 1e3;
|
|
22
18
|
var DEFAULT_AGENT_TURN_TIMEOUT_MS = 12 * 60 * 1e3;
|
|
23
|
-
var
|
|
24
|
-
var
|
|
19
|
+
var DEFAULT_FUNCTION_MAX_DURATION_SECONDS = 800;
|
|
20
|
+
var FUNCTION_TIMEOUT_BUFFER_SECONDS = 20;
|
|
25
21
|
function parseAgentTurnTimeoutMs(rawValue, maxTimeoutMs) {
|
|
26
22
|
const value = Number.parseInt(rawValue ?? "", 10);
|
|
27
23
|
if (Number.isNaN(value)) {
|
|
@@ -32,25 +28,21 @@ function parseAgentTurnTimeoutMs(rawValue, maxTimeoutMs) {
|
|
|
32
28
|
}
|
|
33
29
|
return Math.max(MIN_AGENT_TURN_TIMEOUT_MS, Math.min(value, maxTimeoutMs));
|
|
34
30
|
}
|
|
35
|
-
function
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
10
|
|
39
|
-
);
|
|
31
|
+
function resolveFunctionMaxDurationSeconds(env) {
|
|
32
|
+
const raw = env.FUNCTION_MAX_DURATION_SECONDS ?? env.QUEUE_CALLBACK_MAX_DURATION_SECONDS;
|
|
33
|
+
const value = Number.parseInt(raw ?? "", 10);
|
|
40
34
|
if (Number.isNaN(value) || value <= 0) {
|
|
41
|
-
return
|
|
35
|
+
return DEFAULT_FUNCTION_MAX_DURATION_SECONDS;
|
|
42
36
|
}
|
|
43
37
|
return value;
|
|
44
38
|
}
|
|
45
|
-
function resolveMaxTurnTimeoutMs(
|
|
46
|
-
const budgetSeconds =
|
|
39
|
+
function resolveMaxTurnTimeoutMs(functionMaxDurationSeconds) {
|
|
40
|
+
const budgetSeconds = functionMaxDurationSeconds - FUNCTION_TIMEOUT_BUFFER_SECONDS;
|
|
47
41
|
return Math.max(MIN_AGENT_TURN_TIMEOUT_MS, budgetSeconds * 1e3);
|
|
48
42
|
}
|
|
49
43
|
function readBotConfig(env) {
|
|
50
|
-
const
|
|
51
|
-
const maxTurnTimeoutMs = resolveMaxTurnTimeoutMs(
|
|
52
|
-
queueCallbackMaxDurationSeconds
|
|
53
|
-
);
|
|
44
|
+
const functionMaxDurationSeconds = resolveFunctionMaxDurationSeconds(env);
|
|
45
|
+
const maxTurnTimeoutMs = resolveMaxTurnTimeoutMs(functionMaxDurationSeconds);
|
|
54
46
|
return {
|
|
55
47
|
userName: env.JUNIOR_BOT_NAME ?? "junior",
|
|
56
48
|
modelId: env.AI_MODEL ?? "anthropic/claude-sonnet-4.6",
|
|
@@ -64,9 +56,7 @@ function readBotConfig(env) {
|
|
|
64
56
|
function readChatConfig(env = process.env) {
|
|
65
57
|
return {
|
|
66
58
|
bot: readBotConfig(env),
|
|
67
|
-
|
|
68
|
-
callbackMaxDurationSeconds: resolveQueueCallbackMaxDurationSeconds(env)
|
|
69
|
-
},
|
|
59
|
+
functionMaxDurationSeconds: resolveFunctionMaxDurationSeconds(env),
|
|
70
60
|
slack: {
|
|
71
61
|
botToken: toOptionalTrimmed(env.SLACK_BOT_TOKEN) ?? toOptionalTrimmed(env.SLACK_BOT_USER_TOKEN),
|
|
72
62
|
signingSecret: toOptionalTrimmed(env.SLACK_SIGNING_SECRET),
|
|
@@ -103,6 +93,8 @@ function getRuntimeMetadata() {
|
|
|
103
93
|
}
|
|
104
94
|
|
|
105
95
|
// src/chat/state/adapter.ts
|
|
96
|
+
import { createMemoryState } from "@chat-adapter/state-memory";
|
|
97
|
+
import { createRedisState } from "@chat-adapter/state-redis";
|
|
106
98
|
var MIN_LOCK_TTL_MS = 1e3 * 60 * 5;
|
|
107
99
|
var stateAdapter;
|
|
108
100
|
var redisStateAdapter;
|
|
@@ -122,6 +114,9 @@ function createQueuedStateAdapter(base) {
|
|
|
122
114
|
releaseLock: (lock) => base.releaseLock(lock),
|
|
123
115
|
extendLock: (lock, ttlMs) => base.extendLock(lock, Math.max(ttlMs, MIN_LOCK_TTL_MS)),
|
|
124
116
|
forceReleaseLock: (threadId) => base.forceReleaseLock(threadId),
|
|
117
|
+
enqueue: (threadId, entry, maxSize) => base.enqueue(threadId, entry, maxSize),
|
|
118
|
+
dequeue: (threadId) => base.dequeue(threadId),
|
|
119
|
+
queueDepth: (threadId) => base.queueDepth(threadId),
|
|
125
120
|
get: (key) => base.get(key),
|
|
126
121
|
getList: (key) => base.getList(key),
|
|
127
122
|
set: (key, value, ttlMs) => base.set(key, value, ttlMs),
|
|
@@ -144,18 +139,6 @@ function createStateAdapter() {
|
|
|
144
139
|
redisStateAdapter = redisState;
|
|
145
140
|
return createQueuedStateAdapter(redisState);
|
|
146
141
|
}
|
|
147
|
-
function getOptionalRedisStateAdapter() {
|
|
148
|
-
getStateAdapter();
|
|
149
|
-
return redisStateAdapter;
|
|
150
|
-
}
|
|
151
|
-
async function getConnectedStateContext() {
|
|
152
|
-
const adapter = getStateAdapter();
|
|
153
|
-
await adapter.connect();
|
|
154
|
-
return {
|
|
155
|
-
redisStateAdapter: getOptionalRedisStateAdapter(),
|
|
156
|
-
stateAdapter: adapter
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
142
|
function getStateAdapter() {
|
|
160
143
|
if (!stateAdapter) {
|
|
161
144
|
stateAdapter = createStateAdapter();
|
|
@@ -806,13 +789,13 @@ function isSnapshotMissingError(error) {
|
|
|
806
789
|
|
|
807
790
|
export {
|
|
808
791
|
toOptionalTrimmed,
|
|
792
|
+
getChatConfig,
|
|
809
793
|
botConfig,
|
|
810
794
|
getSlackBotToken,
|
|
811
795
|
getSlackSigningSecret,
|
|
812
796
|
getSlackClientId,
|
|
813
797
|
getSlackClientSecret,
|
|
814
798
|
getRuntimeMetadata,
|
|
815
|
-
getConnectedStateContext,
|
|
816
799
|
getStateAdapter,
|
|
817
800
|
disconnectStateAdapter,
|
|
818
801
|
SANDBOX_WORKSPACE_ROOT,
|
package/dist/cli/init.js
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
function writeRouteModule(filePath, exportLine) {
|
|
5
|
-
fs.writeFileSync(
|
|
5
|
+
fs.writeFileSync(
|
|
6
|
+
filePath,
|
|
7
|
+
`${exportLine}
|
|
6
8
|
export const runtime = "nodejs";
|
|
7
|
-
`
|
|
9
|
+
`
|
|
10
|
+
);
|
|
8
11
|
}
|
|
9
12
|
function writeWrapperFiles(targetDir) {
|
|
10
13
|
const routeDir = path.join(targetDir, "app", "api", "[...path]");
|
|
11
14
|
fs.mkdirSync(routeDir, { recursive: true });
|
|
12
|
-
writeRouteModule(path.join(routeDir, "route.js"), 'export { GET, POST } from "@sentry/junior/handler";');
|
|
13
|
-
const queueRouteDir = path.join(targetDir, "app", "api", "queue", "callback");
|
|
14
|
-
fs.mkdirSync(queueRouteDir, { recursive: true });
|
|
15
15
|
writeRouteModule(
|
|
16
|
-
path.join(
|
|
17
|
-
'export { POST } from "@sentry/junior/
|
|
16
|
+
path.join(routeDir, "route.js"),
|
|
17
|
+
'export { GET, POST } from "@sentry/junior/handler";'
|
|
18
18
|
);
|
|
19
19
|
fs.mkdirSync(path.join(targetDir, "app"), { recursive: true });
|
|
20
20
|
fs.writeFileSync(
|
|
@@ -66,14 +66,20 @@ async function runInit(dir, log = console.log) {
|
|
|
66
66
|
"@sentry/nextjs": "^10.0.0"
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
-
fs.writeFileSync(
|
|
70
|
-
|
|
69
|
+
fs.writeFileSync(
|
|
70
|
+
path.join(target, "package.json"),
|
|
71
|
+
`${JSON.stringify(pkg, null, 2)}
|
|
72
|
+
`
|
|
73
|
+
);
|
|
71
74
|
const dataDir = path.join(target, "app", "data");
|
|
72
75
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
73
|
-
fs.writeFileSync(
|
|
76
|
+
fs.writeFileSync(
|
|
77
|
+
path.join(dataDir, "SOUL.md"),
|
|
78
|
+
`# ${name}
|
|
74
79
|
|
|
75
80
|
You are ${name}, a helpful assistant.
|
|
76
|
-
`
|
|
81
|
+
`
|
|
82
|
+
);
|
|
77
83
|
fs.writeFileSync(
|
|
78
84
|
path.join(dataDir, "ABOUT.md"),
|
|
79
85
|
`# About ${name}
|
|
@@ -87,7 +93,10 @@ Describe what ${name} helps users do.
|
|
|
87
93
|
const pluginsDir = path.join(target, "app", "plugins");
|
|
88
94
|
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
89
95
|
fs.writeFileSync(path.join(pluginsDir, ".gitkeep"), "");
|
|
90
|
-
fs.writeFileSync(
|
|
96
|
+
fs.writeFileSync(
|
|
97
|
+
path.join(target, ".gitignore"),
|
|
98
|
+
["node_modules/", ".next/", ".env", ".env.local", ""].join("\n")
|
|
99
|
+
);
|
|
91
100
|
fs.writeFileSync(
|
|
92
101
|
path.join(target, ".env.example"),
|
|
93
102
|
[
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { maxDuration } from './webhooks.js';
|
|
2
|
+
|
|
1
3
|
type RouteContext = {
|
|
2
4
|
params: Promise<unknown>;
|
|
3
5
|
};
|
|
@@ -15,10 +17,6 @@ declare function GET(request: Request, context: RouteContext): Promise<Response>
|
|
|
15
17
|
*
|
|
16
18
|
* Supported routes:
|
|
17
19
|
* - `api/webhooks/:platform`
|
|
18
|
-
* - `api/queue/callback`
|
|
19
|
-
*
|
|
20
|
-
* `queue/callback` is routed here for local/dev parity, but production queue triggers
|
|
21
|
-
* should still target the dedicated `app/api/queue/callback/route.ts` endpoint.
|
|
22
20
|
*/
|
|
23
21
|
declare function POST(request: Request, context: RouteContext): Promise<Response>;
|
|
24
22
|
|
package/dist/handlers/router.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
POST
|
|
3
|
-
} from "../chunk-SO4ORZJR.js";
|
|
4
|
-
import {
|
|
5
|
-
POST
|
|
6
|
-
} from "../chunk-YGERYE7Y.js";
|
|
7
|
-
import {
|
|
2
|
+
POST,
|
|
8
3
|
buildConversationContext,
|
|
9
4
|
buildSlackOutputMessage,
|
|
10
5
|
coerceThreadArtifactsState,
|
|
@@ -16,14 +11,16 @@ import {
|
|
|
16
11
|
formatProviderLabel,
|
|
17
12
|
generateAssistantReply,
|
|
18
13
|
generateConversationId,
|
|
14
|
+
getPersistedThreadState,
|
|
19
15
|
getSlackClient,
|
|
20
16
|
isRetryableTurnError,
|
|
21
17
|
markConversationMessage,
|
|
22
18
|
markTurnCompleted,
|
|
23
19
|
markTurnFailed,
|
|
20
|
+
maxDuration,
|
|
24
21
|
mergeArtifactsState,
|
|
25
22
|
normalizeConversationText,
|
|
26
|
-
|
|
23
|
+
persistThreadStateById,
|
|
27
24
|
publishAppHomeView,
|
|
28
25
|
resolveBaseUrl,
|
|
29
26
|
resolveReplyDelivery,
|
|
@@ -31,15 +28,15 @@ import {
|
|
|
31
28
|
updateConversationStats,
|
|
32
29
|
uploadFilesToThread,
|
|
33
30
|
upsertConversationMessage
|
|
34
|
-
} from "../chunk-
|
|
35
|
-
import {
|
|
36
|
-
botConfig,
|
|
37
|
-
getStateAdapter
|
|
38
|
-
} from "../chunk-FS5Y4CF2.js";
|
|
31
|
+
} from "../chunk-7RM2Y52T.js";
|
|
39
32
|
import {
|
|
40
33
|
GET
|
|
41
34
|
} from "../chunk-4RBEYCOG.js";
|
|
42
35
|
import "../chunk-WM66QDLA.js";
|
|
36
|
+
import {
|
|
37
|
+
botConfig,
|
|
38
|
+
getStateAdapter
|
|
39
|
+
} from "../chunk-BJ4EBVQK.js";
|
|
43
40
|
import {
|
|
44
41
|
buildOAuthTokenRequest,
|
|
45
42
|
getPluginOAuthConfig,
|
|
@@ -53,7 +50,6 @@ import "../chunk-KCLEEKYX.js";
|
|
|
53
50
|
// src/handlers/mcp-oauth-callback.ts
|
|
54
51
|
import { Buffer } from "buffer";
|
|
55
52
|
import { after } from "next/server";
|
|
56
|
-
import { ThreadImpl } from "chat";
|
|
57
53
|
|
|
58
54
|
// src/handlers/oauth-resume.ts
|
|
59
55
|
function resolveReplyTimeoutMs(explicitTimeoutMs) {
|
|
@@ -328,15 +324,6 @@ async function deliverReplyToThread(channelId, threadTs, reply) {
|
|
|
328
324
|
} catch {
|
|
329
325
|
}
|
|
330
326
|
}
|
|
331
|
-
function createSlackThread(channelId, threadTs) {
|
|
332
|
-
return ThreadImpl.fromJSON({
|
|
333
|
-
_type: "chat:Thread",
|
|
334
|
-
adapterName: "slack",
|
|
335
|
-
channelId,
|
|
336
|
-
id: `slack:${channelId}:${threadTs}`,
|
|
337
|
-
isDM: channelId.startsWith("D")
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
327
|
function buildDeterministicTurnId(messageId) {
|
|
341
328
|
const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
342
329
|
return `turn_${sanitized}`;
|
|
@@ -354,16 +341,18 @@ function getUserMessageIdForTurn(conversation, sessionId) {
|
|
|
354
341
|
return void 0;
|
|
355
342
|
}
|
|
356
343
|
async function buildResumeConversationContext(channelId, threadTs, sessionId) {
|
|
357
|
-
const
|
|
358
|
-
const conversation = coerceThreadConversationState(
|
|
344
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
345
|
+
const conversation = coerceThreadConversationState(
|
|
346
|
+
await getPersistedThreadState(threadId)
|
|
347
|
+
);
|
|
359
348
|
const userMessageId = getUserMessageIdForTurn(conversation, sessionId);
|
|
360
349
|
return buildConversationContext(conversation, {
|
|
361
350
|
excludeMessageId: userMessageId
|
|
362
351
|
});
|
|
363
352
|
}
|
|
364
353
|
async function persistCompletedReplyState(channelId, threadTs, sessionId, reply) {
|
|
365
|
-
const
|
|
366
|
-
const currentState = await
|
|
354
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
355
|
+
const currentState = await getPersistedThreadState(threadId);
|
|
367
356
|
const conversation = coerceThreadConversationState(currentState);
|
|
368
357
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
369
358
|
const nextArtifacts = reply.artifactStatePatch ? mergeArtifactsState(artifacts, reply.artifactStatePatch) : void 0;
|
|
@@ -390,7 +379,7 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
|
|
|
390
379
|
nowMs: Date.now(),
|
|
391
380
|
updateConversationStats
|
|
392
381
|
});
|
|
393
|
-
await
|
|
382
|
+
await persistThreadStateById(threadId, {
|
|
394
383
|
artifacts: nextArtifacts,
|
|
395
384
|
conversation,
|
|
396
385
|
sandboxId: reply.sandboxId,
|
|
@@ -398,8 +387,8 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
|
|
|
398
387
|
});
|
|
399
388
|
}
|
|
400
389
|
async function persistFailedReplyState(channelId, threadTs, sessionId) {
|
|
401
|
-
const
|
|
402
|
-
const currentState = await
|
|
390
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
391
|
+
const currentState = await getPersistedThreadState(threadId);
|
|
403
392
|
const conversation = coerceThreadConversationState(currentState);
|
|
404
393
|
markTurnFailed({
|
|
405
394
|
conversation,
|
|
@@ -408,7 +397,7 @@ async function persistFailedReplyState(channelId, threadTs, sessionId) {
|
|
|
408
397
|
markConversationMessage,
|
|
409
398
|
updateConversationStats
|
|
410
399
|
});
|
|
411
|
-
await
|
|
400
|
+
await persistThreadStateById(threadId, {
|
|
412
401
|
conversation
|
|
413
402
|
});
|
|
414
403
|
}
|
|
@@ -549,7 +538,6 @@ async function GET2(request, context) {
|
|
|
549
538
|
|
|
550
539
|
// src/handlers/oauth-callback.ts
|
|
551
540
|
import { after as after2 } from "next/server";
|
|
552
|
-
import { ThreadImpl as ThreadImpl2 } from "chat";
|
|
553
541
|
function htmlErrorResponse(title, message, status) {
|
|
554
542
|
const safeTitle = escapeXml(title);
|
|
555
543
|
const safeMessage = escapeXml(message);
|
|
@@ -569,18 +557,10 @@ function htmlErrorResponse(title, message, status) {
|
|
|
569
557
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
570
558
|
});
|
|
571
559
|
}
|
|
572
|
-
function createSlackThread2(channelId, threadTs) {
|
|
573
|
-
return ThreadImpl2.fromJSON({
|
|
574
|
-
_type: "chat:Thread",
|
|
575
|
-
adapterName: "slack",
|
|
576
|
-
channelId,
|
|
577
|
-
id: `slack:${channelId}:${threadTs}`,
|
|
578
|
-
isDM: channelId.startsWith("D")
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
560
|
async function buildResumeConversationContext2(channelId, threadTs) {
|
|
582
|
-
const
|
|
583
|
-
|
|
561
|
+
const conversation = coerceThreadConversationState(
|
|
562
|
+
await getPersistedThreadState(`slack:${channelId}:${threadTs}`)
|
|
563
|
+
);
|
|
584
564
|
const latestUserMessageId = [...conversation.messages].reverse().find((message) => message.role === "user")?.id;
|
|
585
565
|
return buildConversationContext(conversation, {
|
|
586
566
|
excludeMessageId: latestUserMessageId
|
|
@@ -829,15 +809,12 @@ async function GET4(request, context) {
|
|
|
829
809
|
}
|
|
830
810
|
return new Response("Not Found", { status: 404 });
|
|
831
811
|
}
|
|
832
|
-
async function
|
|
812
|
+
async function POST2(request, context) {
|
|
833
813
|
const route = normalizeRoutePath(getRoutePathParts(await context.params));
|
|
834
|
-
if (route === "queue/callback") {
|
|
835
|
-
return POST(request);
|
|
836
|
-
}
|
|
837
814
|
const webhookMatch = route.match(/^webhooks\/([^/]+)$/);
|
|
838
815
|
if (webhookMatch) {
|
|
839
816
|
const platform = webhookMatch[1];
|
|
840
|
-
return
|
|
817
|
+
return POST(request, {
|
|
841
818
|
params: Promise.resolve({ platform })
|
|
842
819
|
});
|
|
843
820
|
}
|
|
@@ -845,5 +822,6 @@ async function POST3(request, context) {
|
|
|
845
822
|
}
|
|
846
823
|
export {
|
|
847
824
|
GET4 as GET,
|
|
848
|
-
|
|
825
|
+
POST2 as POST,
|
|
826
|
+
maxDuration
|
|
849
827
|
};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel function timeout in seconds.
|
|
3
|
+
*
|
|
4
|
+
* Agent turns run inside `after()` which shares the function's timeout budget.
|
|
5
|
+
* This must be at least as large as the configured turn timeout plus buffer.
|
|
6
|
+
*/
|
|
7
|
+
declare const maxDuration: number;
|
|
1
8
|
/**
|
|
2
9
|
* Webhook route contract for `@sentry/junior`.
|
|
3
10
|
*
|
|
@@ -18,4 +25,4 @@ type WebhookRouteContext = {
|
|
|
18
25
|
*/
|
|
19
26
|
declare function POST(request: Request, context: WebhookRouteContext): Promise<Response>;
|
|
20
27
|
|
|
21
|
-
export { POST };
|
|
28
|
+
export { POST, maxDuration };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
POST
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import "../chunk-FS5Y4CF2.js";
|
|
2
|
+
POST,
|
|
3
|
+
maxDuration
|
|
4
|
+
} from "../chunk-7RM2Y52T.js";
|
|
6
5
|
import "../chunk-WM66QDLA.js";
|
|
6
|
+
import "../chunk-BJ4EBVQK.js";
|
|
7
7
|
import "../chunk-MY7JNCS2.js";
|
|
8
8
|
import "../chunk-KCLEEKYX.js";
|
|
9
9
|
export {
|
|
10
|
-
POST
|
|
10
|
+
POST,
|
|
11
|
+
maxDuration
|
|
11
12
|
};
|
package/dist/next-config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
"./handler": "./dist/handlers/router.js",
|
|
14
14
|
"./handlers/webhooks": "./dist/handlers/webhooks.js",
|
|
15
|
-
"./handlers/queue-callback": "./dist/handlers/queue-callback.js",
|
|
16
15
|
"./handlers/health": "./dist/handlers/health.js",
|
|
17
16
|
"./config": "./dist/next-config.js",
|
|
18
17
|
"./instrumentation": "./dist/instrumentation.js",
|
|
@@ -23,23 +22,22 @@
|
|
|
23
22
|
"bin"
|
|
24
23
|
],
|
|
25
24
|
"dependencies": {
|
|
26
|
-
"@ai-sdk/gateway": "^3.0.
|
|
27
|
-
"@chat-adapter/slack": "4.
|
|
28
|
-
"@chat-adapter/state-memory": "4.
|
|
29
|
-
"@chat-adapter/state-redis": "4.
|
|
25
|
+
"@ai-sdk/gateway": "^3.0.80",
|
|
26
|
+
"@chat-adapter/slack": "4.22.0",
|
|
27
|
+
"@chat-adapter/state-memory": "4.22.0",
|
|
28
|
+
"@chat-adapter/state-redis": "4.22.0",
|
|
30
29
|
"@mariozechner/pi-agent-core": "^0.59.0",
|
|
31
30
|
"@mariozechner/pi-ai": "^0.59.0",
|
|
32
31
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
33
32
|
"@sinclair/typebox": "^0.34.48",
|
|
34
33
|
"@slack/web-api": "^7.15.0",
|
|
35
|
-
"@vercel/
|
|
36
|
-
"
|
|
37
|
-
"ai": "^6.0.116",
|
|
34
|
+
"@vercel/sandbox": "^1.9.0",
|
|
35
|
+
"ai": "^6.0.138",
|
|
38
36
|
"bash-tool": "^1.3.15",
|
|
39
|
-
"chat": "4.
|
|
40
|
-
"just-bash": "^2.
|
|
37
|
+
"chat": "4.22.0",
|
|
38
|
+
"just-bash": "^2.14.0",
|
|
41
39
|
"node-html-markdown": "^2.0.0",
|
|
42
|
-
"yaml": "^2.8.
|
|
40
|
+
"yaml": "^2.8.3",
|
|
43
41
|
"zod": "^4.3.6"
|
|
44
42
|
},
|
|
45
43
|
"peerDependencies": {
|
|
@@ -49,18 +47,18 @@
|
|
|
49
47
|
"react-dom": ">=19.0.0"
|
|
50
48
|
},
|
|
51
49
|
"devDependencies": {
|
|
52
|
-
"@sentry/nextjs": "^10.
|
|
53
|
-
"@types/node": "^25.
|
|
50
|
+
"@sentry/nextjs": "^10.46.0",
|
|
51
|
+
"@types/node": "^25.5.0",
|
|
54
52
|
"@types/react": "^19.2.14",
|
|
55
53
|
"@types/react-dom": "^19.2.3",
|
|
56
|
-
"msw": "^2.12.
|
|
57
|
-
"next": "^16.1
|
|
54
|
+
"msw": "^2.12.14",
|
|
55
|
+
"next": "^16.2.1",
|
|
58
56
|
"react": "^19.2.4",
|
|
59
57
|
"react-dom": "^19.2.4",
|
|
60
58
|
"tsup": "^8.5.1",
|
|
61
59
|
"typescript": "^5.9.3",
|
|
62
|
-
"vercel": "^50.
|
|
63
|
-
"vitest": "^4.1.
|
|
60
|
+
"vercel": "^50.37.0",
|
|
61
|
+
"vitest": "^4.1.1"
|
|
64
62
|
},
|
|
65
63
|
"scripts": {
|
|
66
64
|
"build": "tsup",
|
package/dist/chunk-SO4ORZJR.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getProductionBot
|
|
3
|
-
} from "./chunk-FLP5I4NM.js";
|
|
4
|
-
import {
|
|
5
|
-
createRequestContext,
|
|
6
|
-
logException,
|
|
7
|
-
logWarn,
|
|
8
|
-
setSpanAttributes,
|
|
9
|
-
setSpanStatus,
|
|
10
|
-
withContext,
|
|
11
|
-
withSpan
|
|
12
|
-
} from "./chunk-MY7JNCS2.js";
|
|
13
|
-
|
|
14
|
-
// src/handlers/webhooks.ts
|
|
15
|
-
import { after } from "next/server";
|
|
16
|
-
import * as Sentry from "@sentry/nextjs";
|
|
17
|
-
async function POST(request, context) {
|
|
18
|
-
const bot = getProductionBot();
|
|
19
|
-
const { platform } = await context.params;
|
|
20
|
-
const handler = bot.webhooks[platform];
|
|
21
|
-
const requestContext = createRequestContext(request, { platform });
|
|
22
|
-
const requestUrl = new URL(request.url);
|
|
23
|
-
return withContext(requestContext, async () => {
|
|
24
|
-
if (!handler) {
|
|
25
|
-
const error = new Error(`Unknown platform: ${platform}`);
|
|
26
|
-
logException(
|
|
27
|
-
error,
|
|
28
|
-
"webhook_platform_unknown",
|
|
29
|
-
{},
|
|
30
|
-
{
|
|
31
|
-
"http.response.status_code": 404
|
|
32
|
-
},
|
|
33
|
-
`Unknown platform: ${platform}`
|
|
34
|
-
);
|
|
35
|
-
return new Response(`Unknown platform: ${platform}`, { status: 404 });
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
return await withSpan(
|
|
39
|
-
"http.server.request",
|
|
40
|
-
"http.server",
|
|
41
|
-
requestContext,
|
|
42
|
-
async () => {
|
|
43
|
-
try {
|
|
44
|
-
const activeSpan = Sentry.getActiveSpan();
|
|
45
|
-
const response = await handler(request, {
|
|
46
|
-
waitUntil: (task) => after(() => {
|
|
47
|
-
const runTask = () => {
|
|
48
|
-
const taskOrFactory = task;
|
|
49
|
-
return typeof taskOrFactory === "function" ? taskOrFactory() : taskOrFactory;
|
|
50
|
-
};
|
|
51
|
-
if (activeSpan) {
|
|
52
|
-
return Sentry.withActiveSpan(activeSpan, runTask);
|
|
53
|
-
}
|
|
54
|
-
return runTask();
|
|
55
|
-
})
|
|
56
|
-
});
|
|
57
|
-
if (response.status >= 400) {
|
|
58
|
-
let responseBodySnippet;
|
|
59
|
-
try {
|
|
60
|
-
responseBodySnippet = (await response.clone().text()).slice(
|
|
61
|
-
0,
|
|
62
|
-
300
|
|
63
|
-
);
|
|
64
|
-
} catch {
|
|
65
|
-
responseBodySnippet = void 0;
|
|
66
|
-
}
|
|
67
|
-
logWarn(
|
|
68
|
-
"webhook_non_success_response",
|
|
69
|
-
{},
|
|
70
|
-
{
|
|
71
|
-
"http.response.status_code": response.status,
|
|
72
|
-
"http.request.header.x_slack_signature": request.headers.get("x-slack-signature") ?? void 0,
|
|
73
|
-
"http.request.header.x_slack_request_timestamp": request.headers.get("x-slack-request-timestamp") ?? void 0,
|
|
74
|
-
...responseBodySnippet ? { "app.webhook.response_body": responseBodySnippet } : {}
|
|
75
|
-
},
|
|
76
|
-
`Webhook ${platform} returned ${response.status}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
setSpanAttributes({
|
|
80
|
-
"http.response.status_code": response.status
|
|
81
|
-
});
|
|
82
|
-
setSpanStatus(response.status >= 500 ? "error" : "ok");
|
|
83
|
-
return response;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
setSpanStatus("error");
|
|
86
|
-
throw error;
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"http.request.method": request.method,
|
|
91
|
-
"url.path": requestUrl.pathname
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
logException(error, "webhook_handler_failed");
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export {
|
|
102
|
-
POST
|
|
103
|
-
};
|