@sentry/junior 0.132.0 → 0.134.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/{agent-hooks-ONXOJDR6.js → agent-hooks-HGXNYOOD.js} +9 -9
- package/dist/api/schema/task.d.ts +60 -0
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +3 -1
- package/dist/api.js +90 -20
- package/dist/app.js +110 -39
- package/dist/{catalog-runtime-BATAY4R7.js → catalog-runtime-P6QHU6XE.js} +5 -5
- package/dist/chat/agent/prompt.d.ts +7 -5
- package/dist/chat/agent/repository-context.d.ts +20 -0
- package/dist/chat/agent/sandbox.d.ts +8 -0
- package/dist/chat/agent/tools.d.ts +3 -0
- package/dist/chat/config.d.ts +2 -0
- package/dist/chat/conversations/projection.d.ts +3 -1
- package/dist/chat/conversations/sql/bindings.d.ts +13 -0
- package/dist/chat/conversations/sql/store.d.ts +3 -0
- package/dist/chat/conversations/store.d.ts +15 -0
- package/dist/chat/plugins/agent-hooks.d.ts +2 -2
- package/dist/chat/repository-instructions.d.ts +44 -0
- package/dist/chat/runtime/reply-executor.d.ts +1 -0
- package/dist/chat/runtime/slack-runtime.d.ts +2 -0
- package/dist/chat/sandbox/noninteractive-command.d.ts +2 -0
- package/dist/chat/sandbox/sandbox.d.ts +3 -0
- package/dist/chat/sandbox/session.d.ts +1 -0
- package/dist/chat/services/context-compaction.d.ts +1 -0
- package/dist/chat/slack/dispatch-turn.d.ts +1 -0
- package/dist/chat/slack/reply.d.ts +1 -1
- package/dist/chat/slack/tools/user-lookup.d.ts +2 -6
- package/dist/chat/tasks/execution-stats.d.ts +29 -0
- package/dist/chat/tasks/registered.d.ts +3 -0
- package/dist/chat/tools/index.d.ts +2 -0
- package/dist/chat/tools/sandbox/bash.d.ts +1 -0
- package/dist/chat/tools/system-time.d.ts +11 -1
- package/dist/{chunk-O2UXPUVQ.js → chunk-52DIKFJV.js} +14 -6
- package/dist/{chunk-GOEZU33G.js → chunk-6T3AYZT7.js} +1 -1
- package/dist/{chunk-GPXVDJML.js → chunk-7GKQ7UIO.js} +449 -39
- package/dist/{chunk-QVEXYYFM.js → chunk-7UTBPDXK.js} +24 -1
- package/dist/{chunk-U76PS7AT.js → chunk-AS3I7OIL.js} +2 -2
- package/dist/{chunk-HX236W2U.js → chunk-CDQ4YIZM.js} +9 -0
- package/dist/{chunk-ODIP5CEM.js → chunk-FDNAUM7X.js} +32 -32
- package/dist/{chunk-GTKNPQNN.js → chunk-FL466XX5.js} +36 -24
- package/dist/{chunk-2425Q4OR.js → chunk-GSP5SMZJ.js} +1 -1
- package/dist/{chunk-XN656LB4.js → chunk-KWGJG4HO.js} +6 -12
- package/dist/{chunk-ISNRPCPG.js → chunk-LKK4XMUV.js} +1 -1
- package/dist/{chunk-G3WYA2RS.js → chunk-MFERLE3G.js} +1 -1
- package/dist/{chunk-ZMV2YBT6.js → chunk-NF2TNZPD.js} +788 -674
- package/dist/chunk-NOA34AJY.js +122 -0
- package/dist/{chunk-JYQAE2ZU.js → chunk-NYWSCJVW.js} +1 -1
- package/dist/{chunk-KB2M27DL.js → chunk-QLEKAO7O.js} +130 -40
- package/dist/{chunk-BKE47OOW.js → chunk-S6DMTEOM.js} +2 -2
- package/dist/{chunk-ALDPUN3Z.js → chunk-TR6UEEYD.js} +8 -6
- package/dist/{chunk-WEJIS7OC.js → chunk-U3ZI7CCW.js} +1 -1
- package/dist/{chunk-B7IY6SVJ.js → chunk-VEGF62FV.js} +1 -1
- package/dist/{chunk-SKWIIUS7.js → chunk-VGXJMECA.js} +7 -7
- package/dist/{chunk-V44FFBO3.js → chunk-VP6NCPRS.js} +1 -1
- package/dist/{chunk-WYQP7QSB.js → chunk-VPYKNCTN.js} +101 -61
- package/dist/{chunk-NNHUGGO4.js → chunk-XG5PHKPM.js} +19 -3
- package/dist/{chunk-AW5Z3T7V.js → chunk-YNLQQ622.js} +9 -8
- package/dist/cli/chat.js +25 -25
- package/dist/cli/check.js +6 -6
- package/dist/cli/init.js +1 -1
- package/dist/cli/plugins.js +12 -12
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +9 -8
- package/dist/db/executor.d.ts +2 -1
- package/dist/db/neon.d.ts +1 -0
- package/dist/db/postgres.d.ts +1 -0
- package/dist/db/schema/conversation-bindings.d.ts +110 -0
- package/dist/db/schema/task-executions.d.ts +110 -0
- package/dist/db/schema.d.ts +221 -1
- package/dist/{db-QFFZACXF.js → db-GFK4NHWJ.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-5WXLD533.js → oauth-callback-server-HUJLAQ5N.js} +19 -18
- package/dist/{runner-Y3LTUNAA.js → runner-T77AFAH4.js} +13 -12
- package/dist/{skills-7M5C24GM.js → skills-3KUFJOOR.js} +6 -6
- package/dist/{validation-MRILMYDI.js → validation-FMWDHKYU.js} +6 -6
- package/dist/version.js +1 -1
- package/migrations/0018_curvy_excalibur.sql +12 -0
- package/migrations/0019_lowly_valkyrie.sql +14 -0
- package/migrations/meta/0018_snapshot.json +1756 -0
- package/migrations/meta/0019_snapshot.json +1904 -0
- package/migrations/meta/_journal.json +15 -1
- package/package.json +5 -5
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JUNIOR_NATIVE_EVENT_NAMESPACE,
|
|
3
|
+
ToolInputError,
|
|
3
4
|
addAgentTurnUsage,
|
|
4
5
|
agentTurnUsageSchema,
|
|
5
6
|
authenticationLinkedEvent,
|
|
6
7
|
authenticationUnlinkedEvent
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CDQ4YIZM.js";
|
|
8
9
|
import {
|
|
9
10
|
agentHistoryItemSchema,
|
|
11
|
+
bindProviderConversation,
|
|
10
12
|
contextProvenance,
|
|
11
13
|
createSqlConversationEventStore,
|
|
12
14
|
getConversationEventStore,
|
|
@@ -16,17 +18,18 @@ import {
|
|
|
16
18
|
instructionProvenanceFor,
|
|
17
19
|
sanitizePostgresJson,
|
|
18
20
|
withConversationEventLock
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VPYKNCTN.js";
|
|
20
22
|
import {
|
|
23
|
+
SANDBOX_WORKSPACE_ROOT,
|
|
21
24
|
getStateAdapter,
|
|
22
25
|
sleep
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-FDNAUM7X.js";
|
|
24
27
|
import {
|
|
25
28
|
botConfig,
|
|
26
29
|
escapeXml,
|
|
27
30
|
resolveGatewayModel,
|
|
28
31
|
unwrapCurrentInstruction
|
|
29
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-XG5PHKPM.js";
|
|
30
33
|
import {
|
|
31
34
|
toStoredSlackActor
|
|
32
35
|
} from "./chunk-HZF5P5UN.js";
|
|
@@ -41,19 +44,35 @@ import {
|
|
|
41
44
|
setSpanAttributes,
|
|
42
45
|
toOptionalNumber,
|
|
43
46
|
toOptionalString
|
|
44
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-6T3AYZT7.js";
|
|
45
48
|
|
|
46
49
|
// src/chat/turn-context-tag.ts
|
|
47
50
|
var TURN_CONTEXT_TAG = "runtime-turn-context";
|
|
48
51
|
|
|
49
52
|
// src/chat/pi/transcript.ts
|
|
50
53
|
var RUNTIME_TURN_CONTEXT_START = `<${TURN_CONTEXT_TAG}>`;
|
|
54
|
+
var AGENTS_INSTRUCTIONS_START = "# AGENTS.md instructions";
|
|
51
55
|
function userMessageContent(message) {
|
|
52
56
|
const record = message;
|
|
53
57
|
return record.role === "user" && Array.isArray(record.content) ? record.content : void 0;
|
|
54
58
|
}
|
|
55
59
|
function isRuntimeTurnContextPart(part) {
|
|
56
|
-
return part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.text.startsWith(RUNTIME_TURN_CONTEXT_START);
|
|
60
|
+
return part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && (part.text.startsWith(RUNTIME_TURN_CONTEXT_START) || part.text.startsWith(AGENTS_INSTRUCTIONS_START));
|
|
61
|
+
}
|
|
62
|
+
function hasCurrentInstruction(message) {
|
|
63
|
+
return userMessageContent(message)?.some(
|
|
64
|
+
(part) => part !== null && typeof part === "object" && part.type === "text" && typeof part.text === "string" && part.text.includes("<current-instruction")
|
|
65
|
+
) ?? false;
|
|
66
|
+
}
|
|
67
|
+
function messageTimestamp(message) {
|
|
68
|
+
return message.timestamp;
|
|
69
|
+
}
|
|
70
|
+
function isStandaloneRuntimeContextMessage(messages, index) {
|
|
71
|
+
const message = messages[index];
|
|
72
|
+
const next = messages[index + 1];
|
|
73
|
+
return Boolean(
|
|
74
|
+
message && next && userMessageContent(message) && userMessageContent(next) && messageTimestamp(message) === messageTimestamp(next) && !hasCurrentInstruction(message) && hasCurrentInstruction(next)
|
|
75
|
+
);
|
|
57
76
|
}
|
|
58
77
|
var EMBEDDED_THREAD_CONTEXT_TAGS = [
|
|
59
78
|
"recent-thread-messages",
|
|
@@ -122,11 +141,14 @@ function trimTrailingAssistantMessages(messages) {
|
|
|
122
141
|
}
|
|
123
142
|
function hasRuntimeTurnContext(messages) {
|
|
124
143
|
return messages.some(
|
|
125
|
-
(message) => userMessageContent(message)?.some(isRuntimeTurnContextPart)
|
|
144
|
+
(message, index) => isStandaloneRuntimeContextMessage(messages, index) || userMessageContent(message)?.some(isRuntimeTurnContextPart)
|
|
126
145
|
);
|
|
127
146
|
}
|
|
128
147
|
function retainRuntimeTurnContext(messages) {
|
|
129
|
-
return messages.flatMap((message) => {
|
|
148
|
+
return messages.flatMap((message, index) => {
|
|
149
|
+
if (isStandaloneRuntimeContextMessage(messages, index)) {
|
|
150
|
+
return [message];
|
|
151
|
+
}
|
|
130
152
|
const runtimeContent = userMessageContent(message)?.filter(isRuntimeTurnContextPart) ?? [];
|
|
131
153
|
return runtimeContent.length > 0 ? [{ ...message, content: runtimeContent }] : [];
|
|
132
154
|
});
|
|
@@ -146,7 +168,10 @@ function getUserMessageInstructionText(message) {
|
|
|
146
168
|
return instructionTextForProjection(text).trim();
|
|
147
169
|
}
|
|
148
170
|
function stripRuntimeTurnContext(messages) {
|
|
149
|
-
return messages.flatMap((message) => {
|
|
171
|
+
return messages.flatMap((message, index) => {
|
|
172
|
+
if (isStandaloneRuntimeContextMessage(messages, index)) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
150
175
|
const content = userMessageContent(message);
|
|
151
176
|
if (!content) return [message];
|
|
152
177
|
const nextContent = content.filter(
|
|
@@ -977,7 +1002,7 @@ async function loadConnectedMcpProviders(args) {
|
|
|
977
1002
|
);
|
|
978
1003
|
return connectedMcpProvidersFromEvents(events);
|
|
979
1004
|
}
|
|
980
|
-
function
|
|
1005
|
+
function messageTimestamp2(message) {
|
|
981
1006
|
const timestamp = message.timestamp;
|
|
982
1007
|
return typeof timestamp === "number" ? timestamp : Date.now();
|
|
983
1008
|
}
|
|
@@ -997,17 +1022,19 @@ async function commitAcceptedReply(args) {
|
|
|
997
1022
|
executor,
|
|
998
1023
|
args.conversationId,
|
|
999
1024
|
async () => executor.transaction(async () => {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1025
|
+
if (args.agentMessage) {
|
|
1026
|
+
const agentMessage = normalizeDurableMessage(args.agentMessage);
|
|
1027
|
+
await createSqlConversationEventStore(executor).append(
|
|
1028
|
+
args.conversationId,
|
|
1029
|
+
[
|
|
1030
|
+
{
|
|
1031
|
+
idempotencyKey: `message:${args.conversationMessageId}:agent`,
|
|
1032
|
+
data: historyItemFromPiMessage(agentMessage, contextProvenance),
|
|
1033
|
+
createdAtMs: messageTimestamp2(agentMessage)
|
|
1034
|
+
}
|
|
1035
|
+
]
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1011
1038
|
await appendConversationMessages(
|
|
1012
1039
|
createSqlConversationEventStore(executor),
|
|
1013
1040
|
{
|
|
@@ -1016,6 +1043,12 @@ async function commitAcceptedReply(args) {
|
|
|
1016
1043
|
...args.repliedAtMs === void 0 ? {} : { repliedAtMs: args.repliedAtMs }
|
|
1017
1044
|
}
|
|
1018
1045
|
);
|
|
1046
|
+
for (const binding of args.providerConversationBindings ?? []) {
|
|
1047
|
+
await bindProviderConversation(executor, {
|
|
1048
|
+
conversationId: args.conversationId,
|
|
1049
|
+
...binding
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1019
1052
|
})
|
|
1020
1053
|
);
|
|
1021
1054
|
}
|
|
@@ -1061,7 +1094,7 @@ async function commitMessagesLocked(args, executor) {
|
|
|
1061
1094
|
message,
|
|
1062
1095
|
nextLocalProvenance[matchingPrefix + index]
|
|
1063
1096
|
),
|
|
1064
|
-
createdAtMs:
|
|
1097
|
+
createdAtMs: messageTimestamp2(message)
|
|
1065
1098
|
})),
|
|
1066
1099
|
...turnContextEvents
|
|
1067
1100
|
]);
|
|
@@ -1390,6 +1423,354 @@ import {
|
|
|
1390
1423
|
} from "@sentry/junior-plugin-api";
|
|
1391
1424
|
import { z as z2 } from "zod";
|
|
1392
1425
|
|
|
1426
|
+
// src/chat/repository-instructions.ts
|
|
1427
|
+
import { createHash as createHash2 } from "crypto";
|
|
1428
|
+
import path2 from "path";
|
|
1429
|
+
|
|
1430
|
+
// src/chat/tools/sandbox/file-utils.ts
|
|
1431
|
+
import path from "path";
|
|
1432
|
+
var MAX_TEXT_CHARS = 6e4;
|
|
1433
|
+
var RIPGREP_EXCLUDED_GLOBS = [
|
|
1434
|
+
"!**/.git/**",
|
|
1435
|
+
"!**/node_modules/**"
|
|
1436
|
+
];
|
|
1437
|
+
var DEFAULT_SEARCH_COMMAND_TIMEOUT_MS = 3e4;
|
|
1438
|
+
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
|
|
1439
|
+
function positiveInteger2(value) {
|
|
1440
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1441
|
+
return void 0;
|
|
1442
|
+
}
|
|
1443
|
+
const integer = Math.floor(value);
|
|
1444
|
+
return integer > 0 ? integer : void 0;
|
|
1445
|
+
}
|
|
1446
|
+
function normalizeToLf(value) {
|
|
1447
|
+
return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1448
|
+
}
|
|
1449
|
+
function truncateText(value, maxChars = MAX_TEXT_CHARS) {
|
|
1450
|
+
if (value.length <= maxChars) {
|
|
1451
|
+
return { content: value, truncated: false };
|
|
1452
|
+
}
|
|
1453
|
+
const removed = value.length - maxChars;
|
|
1454
|
+
return {
|
|
1455
|
+
content: `${value.slice(0, maxChars)}
|
|
1456
|
+
|
|
1457
|
+
[output truncated: ${removed} characters removed]`,
|
|
1458
|
+
truncated: true
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
function isMissingPathError(error) {
|
|
1462
|
+
if (!error || typeof error !== "object") {
|
|
1463
|
+
return false;
|
|
1464
|
+
}
|
|
1465
|
+
const candidate = error;
|
|
1466
|
+
if (candidate.code === "ENOENT") {
|
|
1467
|
+
return true;
|
|
1468
|
+
}
|
|
1469
|
+
return typeof candidate.message === "string" && candidate.message.startsWith("File not found:");
|
|
1470
|
+
}
|
|
1471
|
+
function missingPathSearchResult(params) {
|
|
1472
|
+
const textPath = params.displayPath ?? params.missingPath ?? params.path;
|
|
1473
|
+
throw new ToolInputError(`Path not found: ${textPath}`);
|
|
1474
|
+
}
|
|
1475
|
+
function escapeRegExp(value) {
|
|
1476
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1477
|
+
}
|
|
1478
|
+
function globToRegExp(pattern) {
|
|
1479
|
+
let source = "";
|
|
1480
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
1481
|
+
const char = pattern[index];
|
|
1482
|
+
const next = pattern[index + 1];
|
|
1483
|
+
if (char === "*" && next === "*") {
|
|
1484
|
+
if (pattern[index + 2] === "/") {
|
|
1485
|
+
source += "(?:.*/)?";
|
|
1486
|
+
index += 2;
|
|
1487
|
+
continue;
|
|
1488
|
+
}
|
|
1489
|
+
source += ".*";
|
|
1490
|
+
index += 1;
|
|
1491
|
+
continue;
|
|
1492
|
+
}
|
|
1493
|
+
if (char === "*") {
|
|
1494
|
+
source += "[^/]*";
|
|
1495
|
+
continue;
|
|
1496
|
+
}
|
|
1497
|
+
if (char === "?") {
|
|
1498
|
+
source += "[^/]";
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
source += escapeRegExp(char);
|
|
1502
|
+
}
|
|
1503
|
+
return new RegExp(`^${source}$`);
|
|
1504
|
+
}
|
|
1505
|
+
function matchesGlob(relativePath, pattern) {
|
|
1506
|
+
const matcher = globToRegExp(pattern);
|
|
1507
|
+
if (matcher.test(relativePath)) {
|
|
1508
|
+
return true;
|
|
1509
|
+
}
|
|
1510
|
+
if (pattern.startsWith("**/") && matchesGlob(relativePath, pattern.slice(3))) {
|
|
1511
|
+
return true;
|
|
1512
|
+
}
|
|
1513
|
+
return !pattern.includes("/") && matcher.test(path.posix.basename(relativePath));
|
|
1514
|
+
}
|
|
1515
|
+
function resolveWorkspacePath(input, fallback = ".") {
|
|
1516
|
+
const requested = (input ?? "").trim() || fallback;
|
|
1517
|
+
const absolute = requested.startsWith("/") ? requested : path.posix.join(SANDBOX_WORKSPACE_ROOT, requested);
|
|
1518
|
+
const normalized = path.posix.normalize(absolute);
|
|
1519
|
+
if (normalized !== SANDBOX_WORKSPACE_ROOT && !normalized.startsWith(`${SANDBOX_WORKSPACE_ROOT}/`)) {
|
|
1520
|
+
throw new ToolInputError(
|
|
1521
|
+
`Path must stay within ${SANDBOX_WORKSPACE_ROOT}: ${requested}`
|
|
1522
|
+
);
|
|
1523
|
+
}
|
|
1524
|
+
return normalized;
|
|
1525
|
+
}
|
|
1526
|
+
function getRipgrepSearchLocation(root, rootIsDirectory) {
|
|
1527
|
+
if (rootIsDirectory) {
|
|
1528
|
+
return { cwd: root, target: "." };
|
|
1529
|
+
}
|
|
1530
|
+
return {
|
|
1531
|
+
cwd: path.posix.dirname(root),
|
|
1532
|
+
target: path.posix.basename(root)
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
async function collectFiles(params) {
|
|
1536
|
+
const files = [];
|
|
1537
|
+
let limitReached = false;
|
|
1538
|
+
let missingPath;
|
|
1539
|
+
const visit = async (dirPath) => {
|
|
1540
|
+
if (missingPath) {
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
let entries;
|
|
1544
|
+
try {
|
|
1545
|
+
entries = (await params.fs.readdir(dirPath)).sort(
|
|
1546
|
+
(a, b) => a.toLowerCase().localeCompare(b.toLowerCase())
|
|
1547
|
+
);
|
|
1548
|
+
} catch (error) {
|
|
1549
|
+
if (isMissingPathError(error)) {
|
|
1550
|
+
missingPath = dirPath;
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
throw error;
|
|
1554
|
+
}
|
|
1555
|
+
for (const entry of entries) {
|
|
1556
|
+
const fullPath = path.posix.join(dirPath, entry);
|
|
1557
|
+
let stat2;
|
|
1558
|
+
try {
|
|
1559
|
+
stat2 = await params.fs.stat(fullPath);
|
|
1560
|
+
} catch (error) {
|
|
1561
|
+
if (isMissingPathError(error)) {
|
|
1562
|
+
missingPath = fullPath;
|
|
1563
|
+
return;
|
|
1564
|
+
}
|
|
1565
|
+
throw error;
|
|
1566
|
+
}
|
|
1567
|
+
if (stat2.isDirectory()) {
|
|
1568
|
+
if (!SKIPPED_DIRECTORIES.has(entry)) {
|
|
1569
|
+
await visit(fullPath);
|
|
1570
|
+
}
|
|
1571
|
+
if (limitReached) return;
|
|
1572
|
+
continue;
|
|
1573
|
+
}
|
|
1574
|
+
const relativePath = path.posix.relative(params.root, fullPath);
|
|
1575
|
+
if (!params.pattern || matchesGlob(relativePath, params.pattern)) {
|
|
1576
|
+
files.push(fullPath);
|
|
1577
|
+
if (params.limit && files.length >= params.limit) {
|
|
1578
|
+
limitReached = true;
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
};
|
|
1584
|
+
let stat;
|
|
1585
|
+
try {
|
|
1586
|
+
stat = await params.fs.stat(params.root);
|
|
1587
|
+
} catch (error) {
|
|
1588
|
+
if (isMissingPathError(error)) {
|
|
1589
|
+
return {
|
|
1590
|
+
files,
|
|
1591
|
+
limitReached: false,
|
|
1592
|
+
missingPath: params.root,
|
|
1593
|
+
missingRoot: true
|
|
1594
|
+
};
|
|
1595
|
+
}
|
|
1596
|
+
throw error;
|
|
1597
|
+
}
|
|
1598
|
+
if (!stat.isDirectory()) {
|
|
1599
|
+
const relativePath = path.posix.basename(params.root);
|
|
1600
|
+
return {
|
|
1601
|
+
files: !params.pattern || matchesGlob(relativePath, params.pattern) ? [params.root] : [],
|
|
1602
|
+
limitReached: false,
|
|
1603
|
+
missingRoot: false
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
await visit(params.root);
|
|
1607
|
+
return {
|
|
1608
|
+
files,
|
|
1609
|
+
limitReached,
|
|
1610
|
+
missingPath,
|
|
1611
|
+
missingRoot: missingPath === params.root
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
// src/chat/repository-instructions.ts
|
|
1616
|
+
var AGENTS_FILENAME = "AGENTS.md";
|
|
1617
|
+
var MAX_REPOSITORY_INSTRUCTIONS_BYTES = 32 * 1024;
|
|
1618
|
+
var AGENTS_REPLACEMENT_NOTICE = "These AGENTS.md instructions replace all previously provided AGENTS.md instructions.";
|
|
1619
|
+
var AGENTS_REMOVAL_NOTICE = "The previously provided AGENTS.md instructions no longer apply.";
|
|
1620
|
+
async function pathExists(fs, target) {
|
|
1621
|
+
try {
|
|
1622
|
+
await fs.stat(target);
|
|
1623
|
+
return true;
|
|
1624
|
+
} catch (error) {
|
|
1625
|
+
if (isMissingPathError(error)) {
|
|
1626
|
+
return false;
|
|
1627
|
+
}
|
|
1628
|
+
throw error;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
async function directoryExists(fs, target) {
|
|
1632
|
+
try {
|
|
1633
|
+
return (await fs.stat(target)).isDirectory();
|
|
1634
|
+
} catch (error) {
|
|
1635
|
+
if (isMissingPathError(error)) {
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
throw error;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
async function findGitRoot(fs, cwd) {
|
|
1642
|
+
let current = cwd;
|
|
1643
|
+
for (; ; ) {
|
|
1644
|
+
if (await pathExists(fs, path2.posix.join(current, ".git"))) {
|
|
1645
|
+
return current;
|
|
1646
|
+
}
|
|
1647
|
+
if (current === SANDBOX_WORKSPACE_ROOT) {
|
|
1648
|
+
return void 0;
|
|
1649
|
+
}
|
|
1650
|
+
const parent = path2.posix.dirname(current);
|
|
1651
|
+
if (parent === current || parent !== SANDBOX_WORKSPACE_ROOT && !parent.startsWith(`${SANDBOX_WORKSPACE_ROOT}/`)) {
|
|
1652
|
+
return void 0;
|
|
1653
|
+
}
|
|
1654
|
+
current = parent;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
async function findSingleRepositoryDirectory(fs) {
|
|
1658
|
+
const entries = await fs.readdir(SANDBOX_WORKSPACE_ROOT);
|
|
1659
|
+
const repositories = [];
|
|
1660
|
+
for (const entry of entries) {
|
|
1661
|
+
const candidate = path2.posix.join(SANDBOX_WORKSPACE_ROOT, entry);
|
|
1662
|
+
if (await directoryExists(fs, candidate) && await pathExists(fs, path2.posix.join(candidate, ".git"))) {
|
|
1663
|
+
repositories.push(candidate);
|
|
1664
|
+
if (repositories.length > 1) {
|
|
1665
|
+
return void 0;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
return repositories[0];
|
|
1670
|
+
}
|
|
1671
|
+
async function readInstructionFile(fs, filePath) {
|
|
1672
|
+
try {
|
|
1673
|
+
const content = await fs.readFile(filePath, { encoding: "utf8" });
|
|
1674
|
+
return content.trim() ? content : void 0;
|
|
1675
|
+
} catch (error) {
|
|
1676
|
+
if (isMissingPathError(error)) {
|
|
1677
|
+
return void 0;
|
|
1678
|
+
}
|
|
1679
|
+
throw error;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
async function resolveRepositoryInstructions(args) {
|
|
1683
|
+
const gitRoot = await findGitRoot(args.fs, args.cwd);
|
|
1684
|
+
if (!gitRoot) {
|
|
1685
|
+
return void 0;
|
|
1686
|
+
}
|
|
1687
|
+
const directories = [];
|
|
1688
|
+
let current = args.cwd;
|
|
1689
|
+
for (; ; ) {
|
|
1690
|
+
directories.push(current);
|
|
1691
|
+
if (current === gitRoot) {
|
|
1692
|
+
break;
|
|
1693
|
+
}
|
|
1694
|
+
current = path2.posix.dirname(current);
|
|
1695
|
+
}
|
|
1696
|
+
directories.reverse();
|
|
1697
|
+
const sources = [];
|
|
1698
|
+
let remaining = MAX_REPOSITORY_INSTRUCTIONS_BYTES;
|
|
1699
|
+
for (const directory of directories) {
|
|
1700
|
+
if (remaining <= 0) {
|
|
1701
|
+
break;
|
|
1702
|
+
}
|
|
1703
|
+
const filePath = path2.posix.join(directory, AGENTS_FILENAME);
|
|
1704
|
+
const content = await readInstructionFile(args.fs, filePath);
|
|
1705
|
+
if (!content) {
|
|
1706
|
+
continue;
|
|
1707
|
+
}
|
|
1708
|
+
const bytes = Buffer.from(content, "utf8");
|
|
1709
|
+
const bounded = bytes.length <= remaining ? content : bytes.subarray(0, remaining).toString("utf8");
|
|
1710
|
+
sources.push({ content: bounded, path: filePath });
|
|
1711
|
+
remaining -= Buffer.byteLength(bounded, "utf8");
|
|
1712
|
+
}
|
|
1713
|
+
if (sources.length === 0) {
|
|
1714
|
+
return void 0;
|
|
1715
|
+
}
|
|
1716
|
+
const text = sources.map((source) => source.content).join("\n\n");
|
|
1717
|
+
const fingerprint = createHash2("sha256").update(JSON.stringify({ directory: args.cwd, sources })).digest("hex");
|
|
1718
|
+
return { directory: args.cwd, fingerprint, sources, text };
|
|
1719
|
+
}
|
|
1720
|
+
function renderAgentsInstructions(args) {
|
|
1721
|
+
const directory = args.directory ? ` for ${args.directory}` : "";
|
|
1722
|
+
return `# AGENTS.md instructions${directory}
|
|
1723
|
+
|
|
1724
|
+
<INSTRUCTIONS>
|
|
1725
|
+
${args.text}
|
|
1726
|
+
</INSTRUCTIONS>`;
|
|
1727
|
+
}
|
|
1728
|
+
function buildAgentsInstructionsMessage(args) {
|
|
1729
|
+
return {
|
|
1730
|
+
role: "user",
|
|
1731
|
+
content: [{ type: "text", text: renderAgentsInstructions(args) }],
|
|
1732
|
+
timestamp: args.timestamp ?? Date.now()
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
function findVisibleAgentsInstructions(messages) {
|
|
1736
|
+
for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {
|
|
1737
|
+
const message = messages[messageIndex];
|
|
1738
|
+
if (message.role !== "user" || !Array.isArray(message.content)) {
|
|
1739
|
+
continue;
|
|
1740
|
+
}
|
|
1741
|
+
for (let partIndex = message.content.length - 1; partIndex >= 0; partIndex -= 1) {
|
|
1742
|
+
const part = message.content[partIndex];
|
|
1743
|
+
if (part.type !== "text" || typeof part.text !== "string" || !part.text.startsWith("# AGENTS.md instructions")) {
|
|
1744
|
+
continue;
|
|
1745
|
+
}
|
|
1746
|
+
const match = part.text.match(
|
|
1747
|
+
/^# AGENTS\.md instructions(?: for ([^\n]+))?\n\n<INSTRUCTIONS>\n([\s\S]*)\n<\/INSTRUCTIONS>$/
|
|
1748
|
+
);
|
|
1749
|
+
if (!match) {
|
|
1750
|
+
continue;
|
|
1751
|
+
}
|
|
1752
|
+
let text = match[2];
|
|
1753
|
+
if (text === AGENTS_REMOVAL_NOTICE) {
|
|
1754
|
+
return { active: false };
|
|
1755
|
+
}
|
|
1756
|
+
if (text.startsWith(`${AGENTS_REPLACEMENT_NOTICE}
|
|
1757
|
+
|
|
1758
|
+
`)) {
|
|
1759
|
+
text = text.slice(AGENTS_REPLACEMENT_NOTICE.length + 2);
|
|
1760
|
+
}
|
|
1761
|
+
return {
|
|
1762
|
+
active: true,
|
|
1763
|
+
...match[1] ? { directory: match[1] } : {},
|
|
1764
|
+
text
|
|
1765
|
+
};
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
return void 0;
|
|
1769
|
+
}
|
|
1770
|
+
function isAgentsInstructionsMessage(message) {
|
|
1771
|
+
return Boolean(findVisibleAgentsInstructions([message]));
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1393
1774
|
// src/chat/state/turn-session-keys.ts
|
|
1394
1775
|
var AGENT_TURN_SESSION_PREFIX = "junior:agent_turn_session";
|
|
1395
1776
|
function agentTurnSessionKey(conversationId, sessionId) {
|
|
@@ -1521,7 +1902,7 @@ async function recordConversationActivityMetadata(args) {
|
|
|
1521
1902
|
});
|
|
1522
1903
|
}
|
|
1523
1904
|
function materializeAgentTurnSessionRecord(stored, piProjection, turnStartMessageIndex, restoreVolatileContext = true) {
|
|
1524
|
-
const
|
|
1905
|
+
const restoredProjection = restoreVolatileContext && (stored.state === "running" || stored.state === "awaiting_resume") ? restoreRuntimeContext(piProjection, stored.runtimeContext) : piProjection;
|
|
1525
1906
|
return {
|
|
1526
1907
|
version: stored.version,
|
|
1527
1908
|
...stored.channelName ? { channelName: stored.channelName } : {},
|
|
@@ -1532,8 +1913,8 @@ function materializeAgentTurnSessionRecord(stored, piProjection, turnStartMessag
|
|
|
1532
1913
|
startedAtMs: stored.startedAtMs,
|
|
1533
1914
|
lastProgressAtMs: stored.lastProgressAtMs,
|
|
1534
1915
|
updatedAtMs: stored.updatedAtMs,
|
|
1535
|
-
piMessages,
|
|
1536
|
-
piMessageProvenance:
|
|
1916
|
+
piMessages: restoredProjection.messages,
|
|
1917
|
+
piMessageProvenance: restoredProjection.provenance,
|
|
1537
1918
|
actors: stored.actors ?? instructionActors(piProjection.provenance),
|
|
1538
1919
|
cumulativeDurationMs: stored.cumulativeDurationMs,
|
|
1539
1920
|
...stored.destination ? { destination: stored.destination } : {},
|
|
@@ -1554,30 +1935,41 @@ function materializeAgentTurnSessionRecord(stored, piProjection, turnStartMessag
|
|
|
1554
1935
|
...turnStartMessageIndex !== void 0 ? { turnStartMessageIndex } : {}
|
|
1555
1936
|
};
|
|
1556
1937
|
}
|
|
1557
|
-
function restoreRuntimeContext(
|
|
1558
|
-
if (!runtimeContext || runtimeContext.length === 0) return
|
|
1559
|
-
const
|
|
1938
|
+
function restoreRuntimeContext(projection, runtimeContext) {
|
|
1939
|
+
if (!runtimeContext || runtimeContext.length === 0) return projection;
|
|
1940
|
+
const restoredMessages = [...projection.messages];
|
|
1941
|
+
const restoredProvenance = [...projection.provenance];
|
|
1560
1942
|
const unmatchedRuntimeContext = [];
|
|
1561
1943
|
for (const runtimeMessage of runtimeContext) {
|
|
1562
1944
|
const runtime = runtimeMessage;
|
|
1563
|
-
const targetIndex =
|
|
1945
|
+
const targetIndex = restoredMessages.findIndex((message) => {
|
|
1564
1946
|
const candidate = message;
|
|
1565
1947
|
return candidate.role === "user" && candidate.timestamp === runtime.timestamp;
|
|
1566
1948
|
});
|
|
1567
1949
|
if (targetIndex < 0) {
|
|
1568
|
-
|
|
1950
|
+
if (isAgentsInstructionsMessage(runtimeMessage)) {
|
|
1951
|
+
const followingIndex = restoredMessages.findIndex((message) => {
|
|
1952
|
+
const timestamp = message.timestamp;
|
|
1953
|
+
return typeof runtime.timestamp === "number" && typeof timestamp === "number" && timestamp > runtime.timestamp;
|
|
1954
|
+
});
|
|
1955
|
+
const insertionIndex = followingIndex < 0 ? restoredMessages.length : followingIndex;
|
|
1956
|
+
restoredMessages.splice(insertionIndex, 0, runtimeMessage);
|
|
1957
|
+
restoredProvenance.splice(insertionIndex, 0, contextProvenance);
|
|
1958
|
+
} else {
|
|
1959
|
+
unmatchedRuntimeContext.push(runtimeMessage);
|
|
1960
|
+
}
|
|
1569
1961
|
continue;
|
|
1570
1962
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
...restored[targetIndex],
|
|
1574
|
-
content: [
|
|
1575
|
-
...Array.isArray(runtime.content) ? runtime.content : [],
|
|
1576
|
-
...Array.isArray(target.content) ? target.content : []
|
|
1577
|
-
]
|
|
1578
|
-
};
|
|
1963
|
+
restoredMessages.splice(targetIndex, 0, runtimeMessage);
|
|
1964
|
+
restoredProvenance.splice(targetIndex, 0, contextProvenance);
|
|
1579
1965
|
}
|
|
1580
|
-
return
|
|
1966
|
+
return {
|
|
1967
|
+
messages: [...unmatchedRuntimeContext, ...restoredMessages],
|
|
1968
|
+
provenance: [
|
|
1969
|
+
...unmatchedRuntimeContext.map(() => contextProvenance),
|
|
1970
|
+
...restoredProvenance
|
|
1971
|
+
]
|
|
1972
|
+
};
|
|
1581
1973
|
}
|
|
1582
1974
|
async function getStoredAgentTurnSessionRecord(conversationId, sessionId) {
|
|
1583
1975
|
const stateAdapter = getStateAdapter();
|
|
@@ -2935,6 +3327,24 @@ export {
|
|
|
2935
3327
|
recordTurnRoute,
|
|
2936
3328
|
recordToolExecutionStarted,
|
|
2937
3329
|
recordGuardianActionReviewed,
|
|
3330
|
+
MAX_TEXT_CHARS,
|
|
3331
|
+
RIPGREP_EXCLUDED_GLOBS,
|
|
3332
|
+
DEFAULT_SEARCH_COMMAND_TIMEOUT_MS,
|
|
3333
|
+
positiveInteger2 as positiveInteger,
|
|
3334
|
+
normalizeToLf,
|
|
3335
|
+
truncateText,
|
|
3336
|
+
isMissingPathError,
|
|
3337
|
+
missingPathSearchResult,
|
|
3338
|
+
resolveWorkspacePath,
|
|
3339
|
+
getRipgrepSearchLocation,
|
|
3340
|
+
collectFiles,
|
|
3341
|
+
AGENTS_REPLACEMENT_NOTICE,
|
|
3342
|
+
AGENTS_REMOVAL_NOTICE,
|
|
3343
|
+
findSingleRepositoryDirectory,
|
|
3344
|
+
resolveRepositoryInstructions,
|
|
3345
|
+
renderAgentsInstructions,
|
|
3346
|
+
buildAgentsInstructionsMessage,
|
|
3347
|
+
findVisibleAgentsInstructions,
|
|
2938
3348
|
buildDeterministicTurnId,
|
|
2939
3349
|
buildDeterministicAssistantMessageId,
|
|
2940
3350
|
ConversationTurnBoundaryError,
|
|
@@ -604,7 +604,11 @@ var taskSummaryBaseSchema = z7.object({
|
|
|
604
604
|
destination: taskDestinationSchema,
|
|
605
605
|
id: z7.string().min(1),
|
|
606
606
|
instruction: z7.string().min(1),
|
|
607
|
-
|
|
607
|
+
lastConversationId: z7.string().min(1).optional(),
|
|
608
|
+
lastRunAt: z7.string().datetime().optional(),
|
|
609
|
+
ownedByViewer: z7.boolean(),
|
|
610
|
+
runsLast7Days: z7.number().int().nonnegative(),
|
|
611
|
+
totalRuns: z7.number().int().nonnegative()
|
|
608
612
|
});
|
|
609
613
|
var scheduledTaskSummarySchema = taskSummaryBaseSchema.extend({
|
|
610
614
|
kind: z7.literal("scheduled"),
|
|
@@ -623,7 +627,25 @@ var taskSummarySchema = z7.discriminatedUnion("kind", [
|
|
|
623
627
|
scheduledTaskSummarySchema,
|
|
624
628
|
eventTaskSummarySchema
|
|
625
629
|
]);
|
|
630
|
+
var registeredTaskSummarySchema = z7.object({
|
|
631
|
+
id: z7.string().min(1),
|
|
632
|
+
lastConversationId: z7.string().min(1).optional(),
|
|
633
|
+
lastRunAt: z7.string().datetime().optional(),
|
|
634
|
+
name: z7.string().min(1),
|
|
635
|
+
pluginDisplayName: z7.string().min(1),
|
|
636
|
+
pluginName: z7.string().min(1),
|
|
637
|
+
runsLast7Days: z7.number().int().nonnegative(),
|
|
638
|
+
totalRuns: z7.number().int().nonnegative()
|
|
639
|
+
}).strict();
|
|
640
|
+
var taskExecutionDaySchema = z7.object({
|
|
641
|
+
date: z7.string().min(1),
|
|
642
|
+
event: z7.number().int().nonnegative(),
|
|
643
|
+
registered: z7.number().int().nonnegative(),
|
|
644
|
+
scheduled: z7.number().int().nonnegative()
|
|
645
|
+
}).strict();
|
|
626
646
|
var taskListSchema = z7.object({
|
|
647
|
+
executionDays: z7.array(taskExecutionDaySchema),
|
|
648
|
+
registeredTasks: z7.array(registeredTaskSummarySchema),
|
|
627
649
|
tasks: z7.array(taskSummarySchema),
|
|
628
650
|
truncated: z7.boolean()
|
|
629
651
|
}).strict();
|
|
@@ -684,6 +706,7 @@ export {
|
|
|
684
706
|
scheduledTaskSummarySchema,
|
|
685
707
|
eventTaskSummarySchema,
|
|
686
708
|
taskSummarySchema,
|
|
709
|
+
registeredTaskSummarySchema,
|
|
687
710
|
taskListSchema,
|
|
688
711
|
taskParamsSchema,
|
|
689
712
|
statSchema,
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-UTL3MHPC.js";
|
|
4
4
|
import {
|
|
5
5
|
parseSlackThreadId
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MFERLE3G.js";
|
|
7
7
|
import {
|
|
8
8
|
normalizeSlackConversationId
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TR6UEEYD.js";
|
|
10
10
|
|
|
11
11
|
// src/handlers/health.ts
|
|
12
12
|
function readHealthReport() {
|
|
@@ -164,11 +164,20 @@ function addAgentTurnUsage(...usages) {
|
|
|
164
164
|
return hasAgentTurnUsage(result) ? result : void 0;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
// src/chat/tools/execution/tool-input-error.ts
|
|
168
|
+
var ToolInputError = class extends Error {
|
|
169
|
+
constructor(message, options) {
|
|
170
|
+
super(message, options);
|
|
171
|
+
this.name = "ToolInputError";
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
167
175
|
export {
|
|
168
176
|
JUNIOR_NATIVE_EVENT_NAMESPACE,
|
|
169
177
|
authenticationLinkedEvent,
|
|
170
178
|
authenticationUnlinkedEvent,
|
|
171
179
|
renderJuniorNativeConversationEvent,
|
|
180
|
+
ToolInputError,
|
|
172
181
|
agentTurnUsageSchema,
|
|
173
182
|
hasAgentTurnUsage,
|
|
174
183
|
addAgentTurnUsage
|