@atolis-hq/wake 0.3.56 → 0.3.57
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.
|
@@ -9,7 +9,7 @@ export function createGitHubAgentContextReader(journal, resources, options = {})
|
|
|
9
9
|
const commentHistory = createCommentHistoryReader(journal, resources, options);
|
|
10
10
|
return {
|
|
11
11
|
async forWorkItem(workItemId, options) {
|
|
12
|
-
const comments = await commentHistory.forWorkItem(workItemId, options);
|
|
12
|
+
const comments = boundedAgentContextComments(await commentHistory.forWorkItem(workItemId, options));
|
|
13
13
|
return {
|
|
14
14
|
...(await currentWorkItemContent(journal, resources, workItemId)),
|
|
15
15
|
comments,
|
|
@@ -18,6 +18,64 @@ export function createGitHubAgentContextReader(journal, resources, options = {})
|
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
const maximumAgentContextComments = 12;
|
|
22
|
+
const maximumAgentContextCommentCharacters = 8_000;
|
|
23
|
+
const maximumAgentContextCharacters = 48_000;
|
|
24
|
+
const truncationNotice = '\n[Wake truncated this historical comment for context bounds.]';
|
|
25
|
+
function boundedAgentContextComments(comments) {
|
|
26
|
+
const indexed = comments.map((comment, index) => ({ comment, index }));
|
|
27
|
+
const latestWakeReviewerFeedback = [...indexed]
|
|
28
|
+
.reverse()
|
|
29
|
+
.find(({ comment }) => isWakeReviewerFeedback(comment));
|
|
30
|
+
const latestWakeAgentArtifact = [...indexed]
|
|
31
|
+
.reverse()
|
|
32
|
+
.find(({ comment }) => isWakeAgentArtifact(comment));
|
|
33
|
+
const protectedWakeArtifacts = [latestWakeReviewerFeedback, latestWakeAgentArtifact].flatMap((candidate, index, values) => candidate === undefined || values.slice(0, index).some((value) => value === candidate)
|
|
34
|
+
? []
|
|
35
|
+
: [candidate]);
|
|
36
|
+
const retained = [];
|
|
37
|
+
let characters = 0;
|
|
38
|
+
for (const artifact of protectedWakeArtifacts) {
|
|
39
|
+
const remaining = maximumAgentContextCharacters - characters;
|
|
40
|
+
if (remaining <= 0)
|
|
41
|
+
break;
|
|
42
|
+
const body = truncateComment(artifact.comment.body, Math.min(maximumAgentContextCommentCharacters, remaining));
|
|
43
|
+
retained.push({ ...artifact, comment: { ...artifact.comment, body } });
|
|
44
|
+
characters += body.length;
|
|
45
|
+
}
|
|
46
|
+
for (const candidate of [...indexed].reverse()) {
|
|
47
|
+
const { comment } = candidate;
|
|
48
|
+
if ((isWakeDelivery(comment.body) && !protectedWakeArtifacts.includes(candidate)) ||
|
|
49
|
+
protectedWakeArtifacts.includes(candidate) ||
|
|
50
|
+
retained.length === maximumAgentContextComments)
|
|
51
|
+
continue;
|
|
52
|
+
const remaining = maximumAgentContextCharacters - characters;
|
|
53
|
+
if (remaining <= 0)
|
|
54
|
+
break;
|
|
55
|
+
const body = truncateComment(comment.body, Math.min(maximumAgentContextCommentCharacters, remaining));
|
|
56
|
+
retained.push({ ...candidate, comment: { ...comment, body } });
|
|
57
|
+
characters += body.length;
|
|
58
|
+
}
|
|
59
|
+
return retained.sort((left, right) => left.index - right.index).map(({ comment }) => comment);
|
|
60
|
+
}
|
|
61
|
+
function isWakeDelivery(body) {
|
|
62
|
+
return /<!--\s*wake:delivery:[^\s>]+\s*-->/.test(body);
|
|
63
|
+
}
|
|
64
|
+
function isWakeReviewerFeedback(comment) {
|
|
65
|
+
return (comment.body.includes('<!-- wake:agent -->') &&
|
|
66
|
+
(comment.body.includes('**Outcome:** 🔴 Changes Requested') ||
|
|
67
|
+
/"watchGateVerdict"[\s\S]*"outcome"\s*:\s*"REJECTED"/.test(comment.body)));
|
|
68
|
+
}
|
|
69
|
+
function isWakeAgentArtifact(comment) {
|
|
70
|
+
return comment.body.includes('<!-- wake:agent -->') && isWakeDelivery(comment.body);
|
|
71
|
+
}
|
|
72
|
+
function truncateComment(body, maximumCharacters) {
|
|
73
|
+
if (body.length <= maximumCharacters)
|
|
74
|
+
return body;
|
|
75
|
+
if (maximumCharacters <= truncationNotice.length)
|
|
76
|
+
return body.slice(0, maximumCharacters);
|
|
77
|
+
return `${body.slice(0, maximumCharacters - truncationNotice.length)}${truncationNotice}`;
|
|
78
|
+
}
|
|
21
79
|
async function currentWorkItemContent(journal, resources, workItemId) {
|
|
22
80
|
const primary = (await resources.correlationsForWork(workItemId)).find((correlation) => correlation.role === ResourceCorrelationRole.Primary);
|
|
23
81
|
if (primary === undefined)
|