@cat-factory/orchestration 0.316.0 → 0.317.1

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.
Files changed (38) hide show
  1. package/dist/container/dependencies.d.ts +12 -1
  2. package/dist/container/dependencies.d.ts.map +1 -1
  3. package/dist/container/engine-collaborators.d.ts.map +1 -1
  4. package/dist/container/engine-collaborators.js +2 -0
  5. package/dist/container/engine-collaborators.js.map +1 -1
  6. package/dist/container/guided-review-module.d.ts +14 -0
  7. package/dist/container/guided-review-module.d.ts.map +1 -0
  8. package/dist/container/guided-review-module.js +27 -0
  9. package/dist/container/guided-review-module.js.map +1 -0
  10. package/dist/container.d.ts +4 -0
  11. package/dist/container.d.ts.map +1 -1
  12. package/dist/container.js.map +1 -1
  13. package/dist/index.d.ts +2 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/modules/board/reviewTaskTarget.d.ts.map +1 -1
  17. package/dist/modules/board/reviewTaskTarget.js +1 -1
  18. package/dist/modules/board/reviewTaskTarget.js.map +1 -1
  19. package/dist/modules/execution/AgentDispatchController.d.ts +1 -1
  20. package/dist/modules/execution/AgentDispatchController.d.ts.map +1 -1
  21. package/dist/modules/execution/AgentDispatchController.js +2 -1
  22. package/dist/modules/execution/AgentDispatchController.js.map +1 -1
  23. package/dist/modules/execution/PrReviewResolutionController.d.ts.map +1 -1
  24. package/dist/modules/execution/PrReviewResolutionController.js +2 -1
  25. package/dist/modules/execution/PrReviewResolutionController.js.map +1 -1
  26. package/dist/modules/guidedReview/GuidedReviewService.d.ts +119 -0
  27. package/dist/modules/guidedReview/GuidedReviewService.d.ts.map +1 -0
  28. package/dist/modules/guidedReview/GuidedReviewService.js +543 -0
  29. package/dist/modules/guidedReview/GuidedReviewService.js.map +1 -0
  30. package/dist/modules/guidedReview/PrExplorer.d.ts +41 -0
  31. package/dist/modules/guidedReview/PrExplorer.d.ts.map +1 -0
  32. package/dist/modules/guidedReview/PrExplorer.js +129 -0
  33. package/dist/modules/guidedReview/PrExplorer.js.map +1 -0
  34. package/dist/modules/guidedReview/guidedReview.logic.d.ts +78 -0
  35. package/dist/modules/guidedReview/guidedReview.logic.d.ts.map +1 -0
  36. package/dist/modules/guidedReview/guidedReview.logic.js +226 -0
  37. package/dist/modules/guidedReview/guidedReview.logic.js.map +1 -0
  38. package/package.json +11 -11
@@ -0,0 +1,543 @@
1
+ import { generateText, stepCountIs } from 'ai';
2
+ import { guidedReviewFailure, } from '@cat-factory/contracts';
3
+ import { catFactoryObservability, GUIDED_REVIEW_AGENT_KIND, GUIDED_REVIEW_ANSWER_SYSTEM_PROMPT, GUIDED_REVIEW_DRAFTS_SYSTEM_PROMPT, GUIDED_REVIEW_OVERVIEW_SYSTEM_PROMPT, guidedReviewTools, renderGuidedReviewAnswerPrompt, renderGuidedReviewDraftsPrompt, renderGuidedReviewOverviewPrompt, } from '@cat-factory/agents';
4
+ import { ConflictError, describeError, extractJson, ForbiddenError, getErrorMessage, NotFoundError, noopLogger, redactSecrets, resolveInlineScope, resolveScopedModelProvider, runBestEffort, UnavailableError, ValidationError, VcsCapabilityUnsupportedError, } from '@cat-factory/kernel';
5
+ import { resolveInlineBlockModelRef } from '../../inlineBlockModel.js';
6
+ import { anchorDrafts, coerceAnswer, coerceDraftProposals, coerceOverview, GUIDED_REVIEW_GENERATION_TIMEOUT_MS, GUIDED_REVIEW_LEASE_MS, GUIDED_REVIEW_MAX_STEPS, OVERVIEW_INLINE_PATCH_CHARS, partitionPatches, THREAD_HISTORY_CHARS, threadHistory, threadTitleFrom, } from './guidedReview.logic.js';
7
+ import { PrExplorer } from './PrExplorer.js';
8
+ /** A model failure the job settles onto its row, rather than a fault the driver should retry. */
9
+ class JobFailure extends Error {
10
+ model;
11
+ failure;
12
+ constructor(failure, model) {
13
+ super(failure.detail ?? failure.reason);
14
+ this.model = model;
15
+ this.failure = settledFailure(failure.reason, failure.detail);
16
+ }
17
+ }
18
+ /**
19
+ * Guided PR review (docs/initiatives/guided-pr-review.md). Requests persist work and return at
20
+ * once; a durable driver calls {@link runJob} to produce the overview or an assistant message.
21
+ *
22
+ * `runJob` claims its row before any model call, so a duplicate delivery is a no-op. A model or
23
+ * VCS failure is settled onto the row with a reason the SPA translates. A repository failure
24
+ * propagates, so the driver retries; the claim lease lets the retry take the job back over.
25
+ */
26
+ export class GuidedReviewService {
27
+ deps;
28
+ logger;
29
+ constructor(deps) {
30
+ this.deps = deps;
31
+ this.logger = deps.logger ?? noopLogger;
32
+ }
33
+ async open(workspaceId, owner, input) {
34
+ const context = await this.repoFor(workspaceId, input);
35
+ const provider = context.provider ?? input.provider ?? 'github';
36
+ const pr = await this.readPr(workspaceId, credentialUser(owner.id, owner.kind), context.repo, provider, input.prNumber);
37
+ const now = this.deps.clock.now();
38
+ const candidate = {
39
+ id: this.deps.idGenerator.next('grs'),
40
+ provider,
41
+ repoId: context.repoId,
42
+ owner: context.owner ?? input.owner,
43
+ repo: context.name ?? input.repo,
44
+ prNumber: input.prNumber,
45
+ prTitle: pr.title,
46
+ reviewedHeadSha: pr.headSha,
47
+ baseRef: pr.baseRef,
48
+ createdBy: owner.id,
49
+ createdByKind: owner.kind,
50
+ createdAt: now,
51
+ updatedAt: now,
52
+ };
53
+ const session = await this.deps.repository.openSession(workspaceId, candidate, this.deps.driver);
54
+ if (session.id === candidate.id) {
55
+ await this.notify(workspaceId, { sessionId: session.id, scope: 'session' });
56
+ await this.wake(workspaceId, { kind: 'overview', sessionId: session.id, generation: 1 });
57
+ }
58
+ return session;
59
+ }
60
+ /** Point the session at the PR's current head and regenerate the overview. Threads are kept. */
61
+ async refresh(workspaceId, userId, sessionId) {
62
+ const session = await this.ownedSession(workspaceId, userId, sessionId);
63
+ const context = await this.repoFor(workspaceId, session);
64
+ const pr = await this.readPr(workspaceId, sessionCredentialUser(session), context.repo, session.provider, session.prNumber);
65
+ const generation = session.overview.generation;
66
+ const moved = await this.deps.repository.restartOverview(workspaceId, sessionId, generation, { prTitle: pr.title, reviewedHeadSha: pr.headSha, baseRef: pr.baseRef }, this.deps.driver, this.deps.clock.now());
67
+ if (moved) {
68
+ await this.notify(workspaceId, { sessionId, scope: 'session' });
69
+ await this.wake(workspaceId, { kind: 'overview', sessionId, generation: generation + 1 });
70
+ }
71
+ return this.requireSession(workspaceId, sessionId);
72
+ }
73
+ listSessions(workspaceId, filter) {
74
+ return this.deps.repository.listSessions(workspaceId, filter);
75
+ }
76
+ /** One keyset page of sessions, newest created first. */
77
+ pageSessions(workspaceId, filter, page) {
78
+ return this.deps.repository.pageSessions(workspaceId, filter, page);
79
+ }
80
+ async getSession(workspaceId, sessionId) {
81
+ const session = await this.requireSession(workspaceId, sessionId);
82
+ const [threads, drafts] = await Promise.all([
83
+ this.deps.repository.listThreads(workspaceId, sessionId),
84
+ this.deps.repository.listDrafts(workspaceId, sessionId),
85
+ ]);
86
+ return { session, threads, drafts };
87
+ }
88
+ async deleteSession(workspaceId, userId, sessionId) {
89
+ await this.ownedSession(workspaceId, userId, sessionId);
90
+ await this.deps.repository.deleteSession(workspaceId, sessionId);
91
+ await this.notify(workspaceId, { sessionId, scope: 'deleted' });
92
+ }
93
+ /** Open a thread, asking its first question when one is given. */
94
+ async openThread(workspaceId, userId, sessionId, input) {
95
+ await this.ownedSession(workspaceId, userId, sessionId);
96
+ // Checked before the thread exists, so a refused question leaves no empty thread behind.
97
+ if (input.question)
98
+ questionText('answer', input.question.content);
99
+ const title = input.title?.trim() || (input.question ? threadTitleFrom(input.question.content) : '');
100
+ const now = this.deps.clock.now();
101
+ const thread = {
102
+ id: this.deps.idGenerator.next('grt'),
103
+ sessionId,
104
+ title,
105
+ createdBy: userId,
106
+ createdAt: now,
107
+ updatedAt: now,
108
+ };
109
+ await this.deps.repository.createThread(workspaceId, thread);
110
+ if (input.question) {
111
+ await this.exchange(workspaceId, thread, 'answer', input.question);
112
+ }
113
+ else {
114
+ await this.notify(workspaceId, { sessionId, scope: 'thread', threadId: thread.id });
115
+ }
116
+ return this.getThread(workspaceId, sessionId, thread.id);
117
+ }
118
+ async getThread(workspaceId, sessionId, threadId) {
119
+ const thread = await this.requireThread(workspaceId, sessionId, threadId);
120
+ const messages = await this.deps.repository.listMessages(workspaceId, threadId);
121
+ return { thread, messages };
122
+ }
123
+ /** Ask a question in a thread. Refused as `thread_busy` while the thread awaits an answer. */
124
+ async ask(workspaceId, userId, sessionId, threadId, input) {
125
+ const thread = await this.ownedThread(workspaceId, userId, sessionId, threadId);
126
+ return this.exchange(workspaceId, thread, 'answer', input);
127
+ }
128
+ /** Turn the thread's conclusions into comment drafts; empty `instructions` asks for all. */
129
+ async requestDrafts(workspaceId, userId, sessionId, threadId, instructions = '') {
130
+ const thread = await this.ownedThread(workspaceId, userId, sessionId, threadId);
131
+ return this.exchange(workspaceId, thread, 'comment-drafts', { content: instructions });
132
+ }
133
+ /** Drive one job. Idempotent: an already-claimed or settled job is a no-op. */
134
+ async runJob(workspaceId, job) {
135
+ if (job.kind === 'overview')
136
+ await this.runOverview(workspaceId, job.sessionId, job.generation);
137
+ else
138
+ await this.runMessage(workspaceId, job.messageId);
139
+ }
140
+ /**
141
+ * Settle a job its driver has given up on (repeated repository faults) as failed, taking over
142
+ * any claim, so the thread stops reading as busy. A settled job is left alone.
143
+ */
144
+ async abandonJob(workspaceId, job, detail) {
145
+ const now = this.deps.clock.now();
146
+ // A cutoff in the future takes over whatever claim the failed attempts left behind.
147
+ const takeover = now + 1;
148
+ const failure = settledFailure('generation_failed', detail);
149
+ if (job.kind === 'overview') {
150
+ const claimed = await this.deps.repository.claimOverview(workspaceId, job.sessionId, job.generation, takeover, now);
151
+ if (!claimed)
152
+ return;
153
+ const landed = await this.deps.repository.settleOverview(workspaceId, job.sessionId, job.generation, { status: 'failed', failure, model: null }, now, claimed);
154
+ if (landed)
155
+ await this.notify(workspaceId, { sessionId: job.sessionId, scope: 'session' });
156
+ return;
157
+ }
158
+ const message = await this.deps.repository.getMessage(workspaceId, job.messageId);
159
+ if (!message)
160
+ return;
161
+ const claimed = await this.deps.repository.claimMessage(workspaceId, job.messageId, takeover, now);
162
+ if (!claimed)
163
+ return;
164
+ const landed = await this.deps.repository.settleMessage(workspaceId, job.messageId, { status: 'failed', failure, model: null }, now, claimed);
165
+ if (!landed)
166
+ return;
167
+ await this.notify(workspaceId, {
168
+ sessionId: message.sessionId,
169
+ scope: 'thread',
170
+ threadId: message.threadId,
171
+ });
172
+ }
173
+ /** Re-wake this driver's jobs that no claim has settled within the lease. */
174
+ async redriveStale(limit = 50) {
175
+ const cutoff = this.deps.clock.now() - GUIDED_REVIEW_LEASE_MS;
176
+ const stale = await this.deps.repository.listStaleJobs(this.deps.driver, cutoff, limit);
177
+ for (const job of stale) {
178
+ const { workspaceId, ...rest } = job;
179
+ await this.wake(workspaceId, rest.kind === 'overview'
180
+ ? { kind: 'overview', sessionId: rest.sessionId, generation: rest.generation }
181
+ : { kind: 'message', messageId: rest.messageId });
182
+ }
183
+ return stale.length;
184
+ }
185
+ async exchange(workspaceId, thread, kind, input) {
186
+ const content = questionText(kind, input.content);
187
+ const result = await this.deps.repository.appendExchange(workspaceId, {
188
+ sessionId: thread.sessionId,
189
+ threadId: thread.id,
190
+ kind,
191
+ depth: input.depth ?? 'inline',
192
+ questionId: this.deps.idGenerator.next('grm'),
193
+ question: content,
194
+ placeholderId: this.deps.idGenerator.next('grm'),
195
+ at: this.deps.clock.now(),
196
+ }, this.deps.driver);
197
+ if (!result.ok) {
198
+ if (result.reason === 'thread_not_found') {
199
+ throw new NotFoundError('Guided review thread', thread.id);
200
+ }
201
+ throw new ConflictError('This thread is still waiting for its previous answer', 'thread_busy');
202
+ }
203
+ await this.notify(workspaceId, {
204
+ sessionId: thread.sessionId,
205
+ scope: 'thread',
206
+ threadId: thread.id,
207
+ });
208
+ await this.wake(workspaceId, { kind: 'message', messageId: result.placeholder.id });
209
+ return { question: result.question, placeholder: result.placeholder };
210
+ }
211
+ async runOverview(workspaceId, sessionId, generation) {
212
+ const now = this.deps.clock.now();
213
+ const claimed = await this.deps.repository.claimOverview(workspaceId, sessionId, generation, now - GUIDED_REVIEW_LEASE_MS, now);
214
+ if (!claimed)
215
+ return;
216
+ const session = await this.requireSession(workspaceId, sessionId);
217
+ let outcome;
218
+ try {
219
+ const pr = await this.bindPr(workspaceId, session);
220
+ const body = await this.asUser(workspaceId, sessionCredentialUser(session), () => pr.repo.getPullRequestBody ? pr.repo.getPullRequestBody(session.prNumber) : null);
221
+ const { inline, omitted } = partitionPatches(pr.files, OVERVIEW_INLINE_PATCH_CHARS);
222
+ const { text, model } = await this.generate(workspaceId, session, 'overview', {
223
+ system: GUIDED_REVIEW_OVERVIEW_SYSTEM_PROMPT,
224
+ prompt: renderGuidedReviewOverviewPrompt({
225
+ pr: pr.header,
226
+ body: body?.trim() ? body : null,
227
+ files: pr.files,
228
+ inlinePatches: inline,
229
+ omittedPatchPaths: omitted,
230
+ }),
231
+ tools: guidedReviewTools(new PrExplorer(pr.repo, this.target(session), pr.files)),
232
+ });
233
+ const content = coerceOverview(extractJson(text), () => this.deps.idGenerator.next('grq'));
234
+ if (!content)
235
+ throw new JobFailure({ reason: 'unreadable_reply', detail: text }, model);
236
+ outcome = { status: 'complete', content, model };
237
+ }
238
+ catch (error) {
239
+ outcome = { status: 'failed', ...this.failureOf(error, workspaceId, sessionId) };
240
+ }
241
+ const landed = await this.deps.repository.settleOverview(workspaceId, sessionId, generation, outcome, this.deps.clock.now(), claimed);
242
+ if (landed)
243
+ await this.notify(workspaceId, { sessionId, scope: 'session' });
244
+ }
245
+ async runMessage(workspaceId, messageId) {
246
+ const message = await this.deps.repository.getMessage(workspaceId, messageId);
247
+ if (!message || message.role !== 'assistant')
248
+ return;
249
+ const now = this.deps.clock.now();
250
+ const claimed = await this.deps.repository.claimMessage(workspaceId, messageId, now - GUIDED_REVIEW_LEASE_MS, now);
251
+ if (!claimed)
252
+ return;
253
+ const [session, messages] = await Promise.all([
254
+ this.requireSession(workspaceId, message.sessionId),
255
+ this.deps.repository.listMessages(workspaceId, message.threadId),
256
+ ]);
257
+ const settledAt = () => this.deps.clock.now();
258
+ let landed = false;
259
+ let draftsLanded = false;
260
+ try {
261
+ if (message.depth === 'deep') {
262
+ throw new JobFailure({ reason: 'depth_unavailable', detail: null }, null);
263
+ }
264
+ const pr = await this.bindPr(workspaceId, session);
265
+ const thread = threadHistory(messages.filter((m) => m.seq < message.seq), THREAD_HISTORY_CHARS);
266
+ const promptInput = { pr: pr.header, overview: session.overview.content, ...thread };
267
+ const tools = guidedReviewTools(new PrExplorer(pr.repo, this.target(session), pr.files));
268
+ if (message.kind === 'answer') {
269
+ const { text, model } = await this.generate(workspaceId, session, 'answer', {
270
+ system: GUIDED_REVIEW_ANSWER_SYSTEM_PROMPT,
271
+ prompt: renderGuidedReviewAnswerPrompt(promptInput),
272
+ tools,
273
+ });
274
+ const answer = coerceAnswer(extractJson(text));
275
+ if (!answer)
276
+ throw new JobFailure({ reason: 'unreadable_reply', detail: text }, model);
277
+ landed = await this.deps.repository.settleMessage(workspaceId, messageId, { status: 'complete', ...answer, draftReport: null, model }, settledAt(), claimed);
278
+ }
279
+ else {
280
+ draftsLanded = landed = await this.settleDraftJob(workspaceId, session, {
281
+ messageId,
282
+ claimed,
283
+ files: pr.files,
284
+ promptInput,
285
+ tools,
286
+ });
287
+ }
288
+ }
289
+ catch (error) {
290
+ const { failure, model } = this.failureOf(error, workspaceId, session.id);
291
+ landed = await this.deps.repository.settleMessage(workspaceId, messageId, { status: 'failed', failure, model }, settledAt(), claimed);
292
+ }
293
+ if (landed) {
294
+ await this.notify(workspaceId, {
295
+ sessionId: session.id,
296
+ scope: draftsLanded ? 'drafts' : 'thread',
297
+ threadId: message.threadId,
298
+ });
299
+ }
300
+ }
301
+ /** Produce a `comment-drafts` message's drafts and land them with it, atomically. */
302
+ async settleDraftJob(workspaceId, session, job) {
303
+ const { messageId, claimed, files, promptInput, tools } = job;
304
+ const { text, model } = await this.generate(workspaceId, session, 'drafts', {
305
+ system: GUIDED_REVIEW_DRAFTS_SYSTEM_PROMPT,
306
+ prompt: renderGuidedReviewDraftsPrompt(promptInput),
307
+ tools,
308
+ });
309
+ const raw = extractJson(text);
310
+ if (raw === null || typeof raw !== 'object') {
311
+ throw new JobFailure({ reason: 'unreadable_reply', detail: text }, model);
312
+ }
313
+ const { proposals, incomplete } = coerceDraftProposals(raw);
314
+ const { kept, report } = anchorDrafts(proposals, incomplete, files);
315
+ const drafts = kept.map((p) => ({
316
+ id: this.deps.idGenerator.next('grd'),
317
+ ...p,
318
+ }));
319
+ return this.deps.repository.settleDrafts(workspaceId, messageId, drafts, { status: 'complete', content: '', citations: [], draftReport: report, model }, this.deps.clock.now(), claimed);
320
+ }
321
+ /** Run one bounded tool loop under the session creator's model scope and budget. */
322
+ async generate(workspaceId, session, phase, call) {
323
+ if (await this.deps.isOverBudget?.(workspaceId)) {
324
+ throw new JobFailure({ reason: 'budget_exhausted', detail: null }, null);
325
+ }
326
+ const { modelProvider, ref } = await this.resolveModel(workspaceId, sessionCredentialUser(session));
327
+ const model = `${ref.provider}:${ref.model}`;
328
+ const maxSteps = GUIDED_REVIEW_MAX_STEPS[phase];
329
+ try {
330
+ // The tools read the VCS, so the whole loop runs under the creator's credential scope.
331
+ const result = await this.asUser(workspaceId, sessionCredentialUser(session), () => generateText({
332
+ model: modelProvider.resolve(ref),
333
+ system: call.system,
334
+ prompt: call.prompt,
335
+ tools: call.tools,
336
+ stopWhen: stepCountIs(maxSteps),
337
+ // The last step may not call a tool, so a loop that reaches the cap still ends on a reply.
338
+ prepareStep: ({ stepNumber }) => stepNumber >= maxSteps - 1 ? { toolChoice: 'none' } : {},
339
+ temperature: 0.2,
340
+ maxOutputTokens: 8_000,
341
+ abortSignal: AbortSignal.timeout(GUIDED_REVIEW_GENERATION_TIMEOUT_MS),
342
+ providerOptions: catFactoryObservability({
343
+ agentKind: GUIDED_REVIEW_AGENT_KIND,
344
+ workspaceId,
345
+ }),
346
+ }));
347
+ const text = result.text.trim();
348
+ if (!text)
349
+ throw new JobFailure({ reason: 'unreadable_reply', detail: null }, model);
350
+ return { text, model };
351
+ }
352
+ catch (error) {
353
+ if (error instanceof JobFailure)
354
+ throw error;
355
+ throw new JobFailure({ reason: 'generation_failed', detail: getErrorMessage(error) }, model);
356
+ }
357
+ }
358
+ /** The model under `userId`'s scope, or the workspace's when the session has no person. */
359
+ async resolveModel(workspaceId, userId) {
360
+ const scope = await resolveInlineScope(userId === null ? { kind: 'workspace', workspaceId } : { kind: 'user', workspaceId, userId });
361
+ const modelProvider = await resolveScopedModelProvider(scope, this.deps);
362
+ const ref = await resolveInlineBlockModelRef(this.deps, workspaceId, GUIDED_REVIEW_AGENT_KIND, {});
363
+ if (!modelProvider || !ref) {
364
+ throw new JobFailure({ reason: 'model_unavailable', detail: null }, null);
365
+ }
366
+ return { modelProvider, ref };
367
+ }
368
+ /** The PR as reviewed: its changed files at the session's head, bound for reading. */
369
+ async bindPr(workspaceId, session) {
370
+ let context;
371
+ try {
372
+ context = await this.repoFor(workspaceId, session);
373
+ }
374
+ catch (error) {
375
+ throw new JobFailure({ reason: 'repo_unavailable', detail: getErrorMessage(error) }, null);
376
+ }
377
+ const listChangedFiles = context.repo.listChangedFiles?.bind(context.repo);
378
+ const getPullRequest = context.repo.getPullRequest?.bind(context.repo);
379
+ if (!listChangedFiles || !getPullRequest) {
380
+ throw new JobFailure({ reason: 'repo_unavailable', detail: 'This VCS connection cannot read pull requests' }, null);
381
+ }
382
+ let files;
383
+ let currentHead;
384
+ try {
385
+ ;
386
+ [files, currentHead] = await this.asUser(workspaceId, sessionCredentialUser(session), async () => {
387
+ const listed = await listChangedFiles(session.prNumber);
388
+ // Read after the listing: a push between the two reads then shows up as a moved head.
389
+ const pr = await getPullRequest(session.prNumber);
390
+ if (!pr?.headSha)
391
+ throw new Error(`Pull request #${session.prNumber} was not found`);
392
+ return [listed, pr.headSha];
393
+ });
394
+ }
395
+ catch (error) {
396
+ throw new JobFailure({ reason: 'repo_unavailable', detail: getErrorMessage(error) }, null);
397
+ }
398
+ // The host lists the files of the PR's CURRENT head. Past a push they no longer describe the
399
+ // commit the session reviews, so answering or anchoring drafts against them would mix commits.
400
+ if (currentHead !== session.reviewedHeadSha) {
401
+ throw new JobFailure({ reason: 'head_moved', detail: currentHead }, null);
402
+ }
403
+ return {
404
+ repo: context.repo,
405
+ files,
406
+ header: {
407
+ owner: session.owner,
408
+ repo: session.repo,
409
+ prNumber: session.prNumber,
410
+ title: session.prTitle,
411
+ headSha: session.reviewedHeadSha,
412
+ baseRef: session.baseRef,
413
+ },
414
+ };
415
+ }
416
+ async repoFor(workspaceId, coords) {
417
+ const resolve = this.deps.resolveRepoFilesForCoords;
418
+ if (!resolve) {
419
+ throw new UnavailableError('No source control integration is configured', 'vcs_not_configured');
420
+ }
421
+ const context = await resolve(workspaceId, {
422
+ owner: coords.owner,
423
+ repo: coords.repo,
424
+ ...(coords.provider ? { provider: coords.provider } : {}),
425
+ });
426
+ if (!context) {
427
+ throw new NotFoundError('Repository', `${coords.owner}/${coords.repo}`, {
428
+ reason: 'repo_not_linked',
429
+ });
430
+ }
431
+ return context;
432
+ }
433
+ async readPr(workspaceId, userId, repo, provider, prNumber) {
434
+ const getPullRequest = repo.getPullRequest?.bind(repo);
435
+ if (!getPullRequest || !repo.listChangedFiles) {
436
+ throw new VcsCapabilityUnsupportedError(provider, 'pull request reads');
437
+ }
438
+ const pr = await this.asUser(workspaceId, userId, () => getPullRequest(prNumber));
439
+ if (!pr || !pr.headSha || !pr.baseRef) {
440
+ throw new NotFoundError('Pull request', String(prNumber), { reason: 'pr_not_found' });
441
+ }
442
+ return { title: pr.title, headSha: pr.headSha, baseRef: pr.baseRef };
443
+ }
444
+ /**
445
+ * Run a VCS call under `userId`'s credential scope (the initiator-PAT policy applies), or
446
+ * attributed to nobody when the session has no person behind it.
447
+ */
448
+ asUser(workspaceId, userId, fn) {
449
+ const scope = this.deps.runInitiatorScope;
450
+ return scope ? scope({ workspaceId, initiatedBy: userId }, fn) : fn();
451
+ }
452
+ target(session) {
453
+ return { headSha: session.reviewedHeadSha, baseRef: session.baseRef };
454
+ }
455
+ /** Map a job's failure to what is settled on its row; anything unexpected is logged once. */
456
+ failureOf(error, workspaceId, sessionId) {
457
+ if (error instanceof JobFailure)
458
+ return { failure: error.failure, model: error.model };
459
+ this.logger.warn('guided review job failed unexpectedly', {
460
+ workspaceId,
461
+ sessionId,
462
+ ...describeError(error),
463
+ });
464
+ return {
465
+ failure: settledFailure('generation_failed', getErrorMessage(error)),
466
+ model: null,
467
+ };
468
+ }
469
+ async wake(workspaceId, job) {
470
+ const runner = this.deps.runner;
471
+ if (!runner)
472
+ return;
473
+ // Best-effort: the row is already committed, and a lost wake is re-driven by the sweeper.
474
+ await runBestEffort(this.logger, 'guidedReview.wake', () => runner.start(workspaceId, job), {
475
+ workspaceId,
476
+ job: job.kind,
477
+ });
478
+ }
479
+ async requireSession(workspaceId, sessionId) {
480
+ const session = await this.deps.repository.getSession(workspaceId, sessionId);
481
+ if (!session)
482
+ throw new NotFoundError('Guided review session', sessionId);
483
+ return session;
484
+ }
485
+ async ownedSession(workspaceId, userId, sessionId) {
486
+ const session = await this.requireSession(workspaceId, sessionId);
487
+ if (session.createdBy !== userId) {
488
+ throw new ForbiddenError('Only the reviewer who opened this guided review can change it', {
489
+ reason: 'not_session_owner',
490
+ });
491
+ }
492
+ return session;
493
+ }
494
+ /** A thread of `sessionId`; one belonging to another session is reported as absent. */
495
+ async requireThread(workspaceId, sessionId, threadId) {
496
+ const thread = await this.deps.repository.getThread(workspaceId, threadId);
497
+ if (!thread || thread.sessionId !== sessionId) {
498
+ throw new NotFoundError('Guided review thread', threadId);
499
+ }
500
+ return thread;
501
+ }
502
+ async ownedThread(workspaceId, userId, sessionId, threadId) {
503
+ const thread = await this.requireThread(workspaceId, sessionId, threadId);
504
+ await this.ownedSession(workspaceId, userId, sessionId);
505
+ return thread;
506
+ }
507
+ async notify(workspaceId, change) {
508
+ const events = this.deps.events;
509
+ if (!events?.guidedReviewChanged)
510
+ return;
511
+ // Best-effort: the write is committed, and a client re-reads on reconnect.
512
+ await runBestEffort(this.logger, 'guidedReview.notify', () => events.guidedReviewChanged(workspaceId, change), { workspaceId, sessionId: change.sessionId });
513
+ }
514
+ }
515
+ /** The text a question or drafting request carries; a question may not be empty. */
516
+ function questionText(kind, content) {
517
+ const text = content.trim();
518
+ if (kind === 'answer' && !text) {
519
+ throw new ValidationError('A question cannot be empty', { reason: 'empty_question' });
520
+ }
521
+ return text;
522
+ }
523
+ /**
524
+ * A failure as stored on a row. The detail is raw model text or a provider error, so it is scrubbed
525
+ * of secrets and then cut to what the contract admits.
526
+ */
527
+ function settledFailure(reason, detail) {
528
+ const scrubbed = detail === null ? '' : (redactSecrets(detail) ?? '').trim();
529
+ return guidedReviewFailure(reason, scrubbed || null);
530
+ }
531
+ /** The person whose credentials an owner's work runs under; null for an unbound API key. */
532
+ function credentialUser(id, kind) {
533
+ switch (kind) {
534
+ case 'user':
535
+ return id;
536
+ case 'api-key':
537
+ return null;
538
+ }
539
+ }
540
+ function sessionCredentialUser(session) {
541
+ return credentialUser(session.createdBy, session.createdByKind);
542
+ }
543
+ //# sourceMappingURL=GuidedReviewService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GuidedReviewService.js","sourceRoot":"","sources":["../../../src/modules/guidedReview/GuidedReviewService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { GuidedReviewExplorer, GuidedReviewFileRequest } from '@cat-factory/agents';
2
+ import type { GitHubChangedFile, RepoFiles } from '@cat-factory/kernel';
3
+ /** How much one job may read, and how much one read may return. */
4
+ export interface PrExplorerLimits {
5
+ /** Tool reads per job; past it every tool says the budget is spent. */
6
+ maxReads: number;
7
+ /** Lines one `read_file` returns before it truncates and says where to resume. */
8
+ maxFileLines: number;
9
+ /** Characters one answer returns before it truncates. */
10
+ maxChars: number;
11
+ }
12
+ export declare const DEFAULT_PR_EXPLORER_LIMITS: PrExplorerLimits;
13
+ export interface PrExplorerTarget {
14
+ headSha: string;
15
+ baseRef: string;
16
+ }
17
+ /**
18
+ * Reads one pull request for a guided-review model call, pinned to the reviewed head. Every
19
+ * answer is text the model reads directly: the content, or the sentence saying why there is
20
+ * none, so an unreadable file is a stated fact rather than an aborted generation. Content is
21
+ * scrubbed of secrets before the model sees it, since answers are stored and shown.
22
+ */
23
+ export declare class PrExplorer implements GuidedReviewExplorer {
24
+ private readonly repo;
25
+ private readonly target;
26
+ private readonly files;
27
+ private readonly limits;
28
+ private reads;
29
+ private readonly byPath;
30
+ constructor(repo: RepoFiles, target: PrExplorerTarget, files: GitHubChangedFile[], limits?: PrExplorerLimits);
31
+ /** Reads this job has spent, for the caller's telemetry. */
32
+ get readsUsed(): number;
33
+ listChangedFiles(): Promise<string>;
34
+ readDiff(path: string): Promise<string>;
35
+ readFile(request: GuidedReviewFileRequest): Promise<string>;
36
+ listDirectory(path: string): Promise<string>;
37
+ private charge;
38
+ private renderLines;
39
+ private bound;
40
+ }
41
+ //# sourceMappingURL=PrExplorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrExplorer.d.ts","sourceRoot":"","sources":["../../../src/modules/guidedReview/PrExplorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAGvE,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAA;IAChB,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAA;IACpB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAIxC,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,oBAAoB;IAKnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IAEvD,YACmB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,iBAAiB,EAAE,EAC1B,MAAM,GAAE,gBAA6C,EAGvE;IAED,4DAA4D;IAC5D,IAAI,SAAS,IAAI,MAAM,CAEtB;IAEK,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAcxC;IAEK,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY5C;IAEK,QAAQ,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAehE;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcjD;YAEa,MAAM;IAWpB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,KAAK;CAOd"}