agents-relay 1.0.124 → 1.0.125

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.
@@ -1,6 +1,6 @@
1
1
  import { storySizeTimeoutMs, taskOverallTimeoutMs } from './types.js';
2
2
  import { schedule, transitionTaskEvent, transitionJobEvent } from './scheduler.js';
3
- import { implementationComplete } from './runtime-status.js';
3
+ import { implementationComplete, implementationTasks } from './runtime-status.js';
4
4
  import { eventFor } from './events.js';
5
5
  import { selectReviewer } from './reviewer-routing.js';
6
6
  import { routeWorker, workerCandidates } from './worker-routing.js';
@@ -26,8 +26,6 @@ export class ReconcilerReviewBase extends ReconcilerRuntimeBase {
26
26
  async ensureFinalReview(job, prState, headSha) {
27
27
  if (job.schedule || job.reviewEnabled === false || prState !== 'OPEN' || job.state !== 'ACTIVE' || !implementationComplete(job) || !headSha)
28
28
  return;
29
- if (!this.preReviewGatesPass(job))
30
- return;
31
29
  const review = job.review;
32
30
  if (review?.headSha === headSha && ['started', 'approved', 'changes_required', 'blocked'].includes(review.outcome))
33
31
  return;
@@ -38,9 +36,9 @@ export class ReconcilerReviewBase extends ReconcilerRuntimeBase {
38
36
  return;
39
37
  const id = `final-review-${headSha.slice(0, 12)}`;
40
38
  const now = new Date().toISOString();
41
- const implementationTasks = job.tasks.filter(item => item.agentName !== 'reviewer' && !this.isSupersededTask(item));
42
- const reviewerRouting = await this.selectReviewer(implementationTasks);
43
- const task = { jobId: job.id, id, kind: 'work', priority: job.priority, storySize: 'M', projectName: job.title, agentName: 'reviewer', parentTaskId: null, dependencies: implementationTasks.map(item => item.id), capabilities: ['review'], workerSelection: reviewerRouting.selection, adapter: reviewerRouting.candidate.adapter, input: `Review existing PR #${job.prNumber} at exactly head SHA ${headSha}. Job objective: ${job.objective ?? job.description ?? job.title}. Use the selected reviewer agent contract as the authoritative review protocol.`, output: { kind: 'task_pr' }, routing: reviewerRouting.candidate.routing, continuation: null, continuationDeliveredAt: null, reviewHeadSha: headSha, state: 'QUEUED', attempt: 0, maxAttempts: this.options.reviewer?.maxAttempts ?? 2, leaseOwner: null, leaseExpiresAt: null, executionId: null, threadId: null, result: null, plannerResult: null, error: null, timeoutMs: this.options.reviewer?.timeoutMs ?? storySizeTimeoutMs('M'), createdAt: now, updatedAt: now };
39
+ const reviewGateTasks = implementationTasks(job);
40
+ const reviewerRouting = await this.selectReviewer(reviewGateTasks);
41
+ const task = { jobId: job.id, id, kind: 'work', priority: job.priority, storySize: 'M', projectName: job.title, agentName: 'reviewer', parentTaskId: null, dependencies: reviewGateTasks.map(item => item.id), capabilities: ['review'], workerSelection: reviewerRouting.selection, adapter: reviewerRouting.candidate.adapter, input: `Review existing PR #${job.prNumber} at exactly head SHA ${headSha}. Job objective: ${job.objective ?? job.description ?? job.title}. Use the selected reviewer agent contract as the authoritative review protocol.`, output: { kind: 'task_pr' }, routing: reviewerRouting.candidate.routing, continuation: null, continuationDeliveredAt: null, reviewHeadSha: headSha, state: 'QUEUED', attempt: 0, maxAttempts: this.options.reviewer?.maxAttempts ?? 2, leaseOwner: null, leaseExpiresAt: null, executionId: null, threadId: null, result: null, plannerResult: null, error: null, timeoutMs: this.options.reviewer?.timeoutMs ?? storySizeTimeoutMs('M'), createdAt: now, updatedAt: now };
44
42
  await this.store.appendTask(task);
45
43
  job.review = { outcome: 'pending', headSha, taskId: id, evidence: null, updatedAt: now };
46
44
  job.updatedAt = now;
@@ -145,12 +143,6 @@ export class ReconcilerReviewBase extends ReconcilerRuntimeBase {
145
143
  await this.emit(eventFor(job.id, task.id, task.parentTaskId, 'model.selected', 'queued', `Selected ${task.routing.model} · thinking ${task.routing.reasoning ?? 'unknown'}`, 'user', { routing: task.routing }, { agent: 'relay', component: 'agents-relay' }));
146
144
  }
147
145
  }
148
- isSupersededTask(task) {
149
- return task.state === 'CANCELLED' && typeof task.error === 'string' && task.error.startsWith('Superseded ');
150
- }
151
- preReviewGatesPass(job) {
152
- return job.tasks.filter(task => task.agentName !== 'reviewer' && !this.isSupersededTask(task)).every(task => task.state === 'SUCCEEDED');
153
- }
154
146
  async applyReviewEvent(event) {
155
147
  const job = await this.store.load(event.job_id);
156
148
  const task = job.tasks.find(item => item.id === event.task_id && item.agentName === 'reviewer');
@@ -2,7 +2,7 @@ function isSuperseded(task) {
2
2
  return task.state === 'CANCELLED' && typeof task.error === 'string' && task.error.startsWith('Superseded ');
3
3
  }
4
4
  export function implementationTasks(job) {
5
- return job.tasks.filter(task => task.agentName !== 'reviewer' && !isSuperseded(task));
5
+ return job.tasks.filter(task => task.agentName !== 'reviewer' && task.agentName !== 'troubleshooter' && !isSuperseded(task));
6
6
  }
7
7
  export function implementationComplete(job) {
8
8
  const tasks = implementationTasks(job);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-relay",
3
- "version": "1.0.124",
3
+ "version": "1.0.125",
4
4
  "description": "Durable async agent jobs coordinated through GitHub pull requests",
5
5
  "type": "module",
6
6
  "bin": {