opencode-magi 0.0.0-dev-20260522075502 → 0.0.0-dev-20260522092014

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.
@@ -343,6 +343,7 @@ async function classifyChecks(input) {
343
343
  }
344
344
  },
345
345
  options: reviewer.options,
346
+ parentSessionId: input.parentSessionId,
346
347
  parse: (text) => {
347
348
  const output = parseCiClassificationOutput(text);
348
349
  for (const check of output.checks) {
@@ -505,6 +506,7 @@ export async function waitForChecksWithClassification(input) {
505
506
  directory: input.directory,
506
507
  onClassifierProgress: input.onClassifierProgress,
507
508
  outputDir: input.outputDir,
509
+ parentSessionId: input.parentSessionId,
508
510
  pr: input.pr,
509
511
  repairAttempts: input.repairAttempts,
510
512
  repository: input.repository,
@@ -96,6 +96,7 @@ async function runEditor(input, worktreePath, cycle, reviewFindings, unresolvedT
96
96
  }
97
97
  },
98
98
  options: editor.options,
99
+ parentSessionId: input.parentSessionId,
99
100
  parse: parseEditOutput,
100
101
  permission: editor.permission,
101
102
  prompt,
@@ -250,6 +251,7 @@ async function runRereview(input, worktreePath, previousHeadSha, cycle, sessionI
250
251
  }
251
252
  },
252
253
  options: reviewer.options,
254
+ parentSessionId: input.parentSessionId,
253
255
  parse: (text) => parseRereviewOutputWithInlineTargets(text, inlineCommentTargets),
254
256
  permission: reviewer.permission,
255
257
  prompt,
@@ -333,6 +335,7 @@ async function runRereview(input, worktreePath, previousHeadSha, cycle, sessionI
333
335
  }
334
336
  },
335
337
  options: reviewer.options,
338
+ parentSessionId: input.parentSessionId,
336
339
  parse: (text) => {
337
340
  const output = parseRereviewCloseReconsiderationOutput(text);
338
341
  validateInlineCommentTargets(output.newFindings, inlineCommentTargets, "newFindings");
@@ -781,6 +784,7 @@ export async function runMerge(input) {
781
784
  exec,
782
785
  headSha: editedHeadSha,
783
786
  onProgress: (phase) => input.onProgress?.({ phase, type: "phase" }),
787
+ parentSessionId: input.parentSessionId,
784
788
  pr: input.pr,
785
789
  repairAttempts: input.config.output?.repairAttempts ?? 3,
786
790
  repository: input.repository,
@@ -89,6 +89,7 @@ function extractText(result, allowEmpty = false) {
89
89
  export async function createModelSession(input) {
90
90
  return extractSessionId(await input.client.session.create({
91
91
  body: {
92
+ parentID: input.parentSessionId,
92
93
  permission: toOpenCodePermissionRules(input.permission),
93
94
  title: input.title,
94
95
  },
@@ -113,6 +114,7 @@ export async function runModelText(input) {
113
114
  throwIfAborted(input.signal);
114
115
  const sessionId = await createModelSession({
115
116
  client: input.client,
117
+ parentSessionId: input.parentSessionId,
116
118
  permission: input.permission,
117
119
  title: input.title,
118
120
  });
@@ -152,6 +154,7 @@ export async function runModelWithRepair(input) {
152
154
  ? input.sessionId
153
155
  : extractSessionId(await input.client.session.create({
154
156
  body: {
157
+ parentID: input.parentSessionId,
155
158
  permission: toOpenCodePermissionRules(input.permission),
156
159
  title: input.title,
157
160
  },
@@ -290,6 +290,7 @@ async function runFindingValidation(input) {
290
290
  }
291
291
  },
292
292
  options: reviewer.options,
293
+ parentSessionId: input.reviewInput.parentSessionId,
293
294
  parse: (text) => {
294
295
  const output = parseFindingValidationOutput(text);
295
296
  validateFindingVotes({
@@ -403,6 +404,7 @@ async function runCloseReconsideration(input) {
403
404
  }
404
405
  },
405
406
  options: reviewer.options,
407
+ parentSessionId: input.reviewInput.parentSessionId,
406
408
  parse: (text) => {
407
409
  const output = parseCloseReconsiderationOutput(text);
408
410
  validateInlineCommentTargets(output.findings, input.inlineCommentTargets);
@@ -567,6 +569,7 @@ export async function runReview(input) {
567
569
  },
568
570
  onProgress: (phase) => input.onProgress?.({ phase, type: "phase" }),
569
571
  outputDir,
572
+ parentSessionId: input.parentSessionId,
570
573
  pr: input.pr,
571
574
  repairAttempts: input.config.output?.repairAttempts ?? 3,
572
575
  repository: input.repository,
@@ -665,6 +668,7 @@ export async function runReview(input) {
665
668
  }
666
669
  },
667
670
  options: reviewer.options,
671
+ parentSessionId: input.parentSessionId,
668
672
  parse: (text) => parseRereviewOutputWithInlineTargets(text, inlineCommentTargets),
669
673
  permission: reviewer.permission,
670
674
  prompt,
@@ -731,6 +735,7 @@ export async function runReview(input) {
731
735
  }
732
736
  },
733
737
  options: reviewer.options,
738
+ parentSessionId: input.parentSessionId,
734
739
  parse: (text) => parseReviewOutputWithInlineTargets(text, inlineCommentTargets),
735
740
  permission: reviewer.permission,
736
741
  prompt,
@@ -403,6 +403,7 @@ function extractQuestionRequest(properties) {
403
403
  export class MagiRunManager {
404
404
  input;
405
405
  active = new Map();
406
+ activeTriageRuns = 0;
406
407
  countedToolParts = new Map();
407
408
  controllers = new Map();
408
409
  eventLastUpdates = new Map();
@@ -410,6 +411,7 @@ export class MagiRunManager {
410
411
  runPaths = new Map();
411
412
  outputDirs = new Set();
412
413
  sessionToRun = new Map();
414
+ triageQueue = [];
413
415
  constructor(input) {
414
416
  this.input = input;
415
417
  }
@@ -581,11 +583,38 @@ export class MagiRunManager {
581
583
  });
582
584
  if (input.sync)
583
585
  return this.executeSync(state, controller, execute, input.timeoutMs);
584
- void execute().catch(async (error) => {
585
- await this.failRun(runId, error);
586
+ this.triageQueue.push({
587
+ execute,
588
+ repository: input.repository,
589
+ runId,
586
590
  });
591
+ this.drainTriageQueue();
587
592
  return state;
588
593
  }
594
+ drainTriageQueue() {
595
+ while (this.triageQueue.length) {
596
+ const next = this.triageQueue[0];
597
+ if (!next)
598
+ return;
599
+ const limit = next.repository.triage?.concurrency.runs ?? 1;
600
+ if (this.activeTriageRuns >= limit)
601
+ return;
602
+ this.triageQueue.shift();
603
+ const state = this.active.get(next.runId);
604
+ if (!state || state.status === "cancelled")
605
+ continue;
606
+ this.activeTriageRuns += 1;
607
+ void next
608
+ .execute()
609
+ .catch(async (error) => {
610
+ await this.failRun(next.runId, error);
611
+ })
612
+ .finally(() => {
613
+ this.activeTriageRuns -= 1;
614
+ this.drainTriageQueue();
615
+ });
616
+ }
617
+ }
589
618
  async status(input = {}) {
590
619
  const timeoutMs = input.timeoutMs;
591
620
  const startedAt = Date.now();
@@ -1263,6 +1292,7 @@ export class MagiRunManager {
1263
1292
  dryRun: input.dryRun,
1264
1293
  exec: withGitHubApiRetry(this.input.exec, input.config.github?.apiRetryAttempts ?? 3),
1265
1294
  onProgress: (progress) => this.applyReviewProgress(input.runId, progress),
1295
+ parentSessionId: input.parentSessionId,
1266
1296
  pr: input.pr,
1267
1297
  repository: input.repository,
1268
1298
  runId: input.runId,
@@ -1318,6 +1348,7 @@ export class MagiRunManager {
1318
1348
  dryRun: input.dryRun,
1319
1349
  exec: withGitHubApiRetry(this.input.exec, input.config.github?.apiRetryAttempts ?? 3),
1320
1350
  onProgress: (progress) => this.applyMergeProgress(input.runId, progress),
1351
+ parentSessionId: input.parentSessionId,
1321
1352
  pr: input.pr,
1322
1353
  repository: input.repository,
1323
1354
  runId: input.runId,
@@ -1359,6 +1390,7 @@ export class MagiRunManager {
1359
1390
  exec: withGitHubApiRetry(this.input.exec, input.config.github?.apiRetryAttempts ?? 3),
1360
1391
  issue: input.issue,
1361
1392
  onProgress: (progress) => this.applyTriageProgress(input.runId, progress),
1393
+ parentSessionId: input.parentSessionId,
1362
1394
  repository: input.repository,
1363
1395
  runId: input.runId,
1364
1396
  signal: input.signal,
@@ -152,6 +152,7 @@ async function runVote(input) {
152
152
  run: input.run,
153
153
  }),
154
154
  options: input.agent.options,
155
+ parentSessionId: input.run.parentSessionId,
155
156
  parse: input.parse,
156
157
  permission: input.agent.permission,
157
158
  prompt,
@@ -476,6 +477,7 @@ async function runActionPrompt(input) {
476
477
  client: input.input.client,
477
478
  model: agent.model,
478
479
  options: agent.options,
480
+ parentSessionId: input.input.parentSessionId,
479
481
  parse: parseTriageActionOutput,
480
482
  permission: agent.permission,
481
483
  prompt,
@@ -505,6 +507,7 @@ async function classifyMentionReplies(input) {
505
507
  client: input.input.client,
506
508
  model: agent.model,
507
509
  options: agent.options,
510
+ parentSessionId: input.input.parentSessionId,
508
511
  parse: parseTriageCommentClassificationOutput,
509
512
  permission: agent.permission,
510
513
  prompt,
@@ -845,6 +848,7 @@ async function createImplementationPr(input) {
845
848
  }
846
849
  },
847
850
  options: creator.options,
851
+ parentSessionId: input.input.parentSessionId,
848
852
  parse: parseTriageCreatePrOutput,
849
853
  permission: creator.permission,
850
854
  prompt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-magi",
3
- "version": "0.0.0-dev-20260522075502",
3
+ "version": "0.0.0-dev-20260522092014",
4
4
  "description": "Multi-agent PR review and merge orchestration plugin for OpenCode.",
5
5
  "license": "MIT",
6
6
  "author": "Hirotomo Yamada <hirotomo.yamada@avap.co.jp>",