@yemi33/minions 0.1.2335 → 0.1.2337
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.
|
@@ -125,7 +125,7 @@ evaluation pass) can see what tooling drove a dispatch:
|
|
|
125
125
|
and ⚠️-marked), and returns `''` for an empty/absent record. The GitHub
|
|
126
126
|
comment path folds it in via `engine/gh-comment.js#buildMinionsCommentBody`
|
|
127
127
|
(optional `harnessUsed` arg, threaded through `postPrComment` /
|
|
128
|
-
`postPrReviewComment`
|
|
128
|
+
`postPrReviewComment`); the Azure DevOps path mirrors it via
|
|
129
129
|
`engine/ado-comment.js#postAdoPrComment` (same builder, same `harnessUsed`
|
|
130
130
|
arg). Both posters are reached from the `minions pr comment` CLI, which turns
|
|
131
131
|
`--harness-file` / `--harness-json` into the grounded record and folds the
|
package/engine/gh-comment.js
CHANGED
|
@@ -210,50 +210,6 @@ function postPrReviewComment({
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
const _REVIEW_EVENT_FLAGS = Object.freeze({
|
|
214
|
-
APPROVE: '--approve',
|
|
215
|
-
REQUEST_CHANGES: '--request-changes',
|
|
216
|
-
COMMENT: '--comment',
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
function postPrReview({
|
|
220
|
-
event,
|
|
221
|
-
repo,
|
|
222
|
-
prNumber,
|
|
223
|
-
body,
|
|
224
|
-
agentId,
|
|
225
|
-
kind,
|
|
226
|
-
workItemId,
|
|
227
|
-
harnessUsed,
|
|
228
|
-
skillSkipped,
|
|
229
|
-
timeoutMs = 30000,
|
|
230
|
-
execFileSync = _execFileSync,
|
|
231
|
-
resolveTokenForSlug,
|
|
232
|
-
} = {}) {
|
|
233
|
-
const flag = _REVIEW_EVENT_FLAGS[event];
|
|
234
|
-
if (!flag) {
|
|
235
|
-
throw new Error(
|
|
236
|
-
`invalid event: ${JSON.stringify(event)} (expected APPROVE | REQUEST_CHANGES | COMMENT)`,
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
_validateRepo(repo);
|
|
240
|
-
_validatePrNumber(prNumber);
|
|
241
|
-
const finalBody = buildMinionsCommentBody({ agentId, kind, workItemId, body, harnessUsed, skillSkipped });
|
|
242
|
-
const file = _writeTempBodyFile(finalBody);
|
|
243
|
-
const env = _resolveTokenEnvForRepo(repo, resolveTokenForSlug);
|
|
244
|
-
try {
|
|
245
|
-
const output = _runGh(
|
|
246
|
-
execFileSync,
|
|
247
|
-
['pr', 'review', String(prNumber), flag, '--repo', repo, '--body-file', file],
|
|
248
|
-
timeoutMs,
|
|
249
|
-
env,
|
|
250
|
-
);
|
|
251
|
-
return { output: String(output || '').trim(), bodyFile: file };
|
|
252
|
-
} finally {
|
|
253
|
-
try { fs.unlinkSync(file); } catch {}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
213
|
module.exports = {
|
|
258
214
|
// Builders / parsers (pure functions — usable from anywhere)
|
|
259
215
|
buildMinionsCommentBody,
|
|
@@ -271,7 +227,6 @@ module.exports = {
|
|
|
271
227
|
// gh wrappers (argv-form, --body-file)
|
|
272
228
|
postPrComment,
|
|
273
229
|
postPrReviewComment,
|
|
274
|
-
postPrReview,
|
|
275
230
|
// Internal helpers exported for tests / advanced callers
|
|
276
231
|
_buildMarker,
|
|
277
232
|
_writeTempBodyFile,
|
|
@@ -652,8 +652,26 @@ function createStreamConsumer(ctx) {
|
|
|
652
652
|
let claudeJoinedText = '';
|
|
653
653
|
const claudeStreamBlocks = new Map();
|
|
654
654
|
|
|
655
|
+
// Only the TRAILING run of text blocks (since the last non-text block)
|
|
656
|
+
// contributes to claudeJoinedText — a tool_use/thinking block closes the
|
|
657
|
+
// run so an earlier text block never welds onto a later one within the
|
|
658
|
+
// SAME message (W-mr9jj2vx000 — CC response duplicates/welds the final
|
|
659
|
+
// answer after ~15 tool calls). Claude can emit content as
|
|
660
|
+
// [text, tool_use, tool_use, ..., text] in one message when
|
|
661
|
+
// --include-partial-messages streams multiple parallel tool calls before
|
|
662
|
+
// a trailing answer; without this, content_block_delta blindly appended
|
|
663
|
+
// every text delta onto the same buffer regardless of the tool_use block
|
|
664
|
+
// in between, producing "<narration><tool icon><narration><answer>" with
|
|
665
|
+
// no paragraph break and no new segment (segmentSeq never bumped because
|
|
666
|
+
// stream-event tool_use blocks don't call ctx.pushToolUse).
|
|
655
667
|
function _rebuildClaudeJoinedText() {
|
|
656
|
-
|
|
668
|
+
const indices = Array.from(claudeStreamBlocks.keys()).sort((a, b) => a - b);
|
|
669
|
+
let start = 0;
|
|
670
|
+
for (let i = indices.length - 1; i >= 0; i--) {
|
|
671
|
+
const block = claudeStreamBlocks.get(indices[i]);
|
|
672
|
+
if (!block || block.type !== 'text') { start = i + 1; break; }
|
|
673
|
+
}
|
|
674
|
+
claudeJoinedText = indices.slice(start)
|
|
657
675
|
.map(index => claudeStreamBlocks.get(index))
|
|
658
676
|
.filter(block => block && block.type === 'text' && block.text)
|
|
659
677
|
.map(block => block.text)
|
|
@@ -673,6 +691,13 @@ function createStreamConsumer(ctx) {
|
|
|
673
691
|
const block = event.content_block || {};
|
|
674
692
|
claudeStreamBlocks.set(index, { type: block.type || '', text: block.text || '' });
|
|
675
693
|
if (THINKING_BLOCK_TYPES.has(block.type)) ctx.notifyThinking();
|
|
694
|
+
// A non-text block (tool_use/thinking) closes the current text run —
|
|
695
|
+
// reset the hot-path accumulator so the NEXT text block starts fresh
|
|
696
|
+
// instead of welding onto text from before this block. `ctx.pushText`
|
|
697
|
+
// already opens a new segment when the pushed value doesn't extend
|
|
698
|
+
// `lastTextSent` (see engine/llm.js), so this reset is sufficient to
|
|
699
|
+
// both stop the weld and trigger the segment boundary.
|
|
700
|
+
if (block.type !== 'text') claudeJoinedText = '';
|
|
676
701
|
// Out-of-order block landing: rebuild from the Map. Common case is
|
|
677
702
|
// monotonic in-order arrival, where the trailing-append branch wins.
|
|
678
703
|
const indices = Array.from(claudeStreamBlocks.keys());
|
|
@@ -735,21 +760,27 @@ function createStreamConsumer(ctx) {
|
|
|
735
760
|
|
|
736
761
|
if (obj.type === 'assistant' && Array.isArray(obj.message?.content)) {
|
|
737
762
|
// Claude assistant turn: content blocks (text + tool_use).
|
|
738
|
-
// Multi-text-block messages (with --include-partial-messages) need
|
|
739
|
-
// text JOINED before pushText, otherwise each block
|
|
763
|
+
// Multi-text-block messages (with --include-partial-messages) need
|
|
764
|
+
// consecutive text blocks JOINED before pushText, otherwise each block
|
|
765
|
+
// overwrites the prior. But a tool_use block closes the current text
|
|
766
|
+
// run — reset the accumulator on tool_use so trailing text starts a
|
|
767
|
+
// fresh segment instead of welding onto text from before the tool
|
|
768
|
+
// call(s) (W-mr9jj2vx0004bbb9 follow-up: this full-envelope path hits
|
|
769
|
+
// the same weld bug as the stream_event path above).
|
|
740
770
|
let assistantText = '';
|
|
741
771
|
for (const block of obj.message.content) {
|
|
742
772
|
if (block?.type === 'text' && block.text) {
|
|
743
773
|
assistantText += block.text;
|
|
774
|
+
ctx.pushText(assistantText);
|
|
744
775
|
} else if (THINKING_BLOCK_TYPES.has(block?.type)) {
|
|
745
776
|
ctx.notifyThinking();
|
|
746
777
|
} else if (block?.type === 'tool_use' && block.name) {
|
|
747
778
|
// Thread the tool_use id so the dashboard can flip this chip from
|
|
748
779
|
// pending → completed/failed when the matching tool_result lands.
|
|
749
780
|
ctx.pushToolUse(block.name, block.input || {}, block.id);
|
|
781
|
+
assistantText = '';
|
|
750
782
|
}
|
|
751
783
|
}
|
|
752
|
-
if (assistantText) ctx.pushText(assistantText);
|
|
753
784
|
}
|
|
754
785
|
|
|
755
786
|
if (obj.type === 'user' && Array.isArray(obj.message?.content)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2337",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|