@effect-agent/pr-review 0.1.0-beta.12 → 0.1.0-beta.13

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.
package/README.md CHANGED
@@ -64,6 +64,15 @@ ephemeral delegation) merged under the same output contract and the same
64
64
  publication path; the shared `guidance` and `maxFindings` shape the
65
65
  coordinator's merge as well as the children.
66
66
 
67
+ GitHub may omit the `patch` field for large textual files as well as binary
68
+ files. The GitHub source recovers a missing patch by reading bounded, strict
69
+ UTF-8 base/head content: additions require the head, deletions require the
70
+ base, and other changes require both. Reviewers receive that content through
71
+ the ordinary diff-read tool with non-anchorable `B`/`H` line labels and must
72
+ report defects as review-body concerns. Invalid UTF-8, binary NUL content,
73
+ missing sides, files beyond the per-side read bound, and complete B/H evidence
74
+ beyond the model-facing render bound remain explicit coverage gaps.
75
+
67
76
  ## What a posted review looks like
68
77
 
69
78
  The body opens with a host-derived callout tier — `[!CAUTION]` when any
@@ -168,11 +177,14 @@ variables inside Actions.
168
177
  ## Bounds, spelled out
169
178
 
170
179
  Finite `AgentPolicy` on every definition plus run-level `UsageBudgetLimits`
171
- (tokens, tool calls, cost, duration). Reading a file head version beyond 200k
172
- characters is refused typed. The changeset surface is bounded at 300 files:
180
+ (tokens, tool calls, cost, duration). Reading either file version beyond 200k
181
+ bytes or characters is refused typed; patchless content is reviewable only
182
+ when its complete B/H rendering fits 220k characters. The changeset surface is
183
+ bounded at 300 files:
173
184
  files beyond the bound are not fetched, and the review body reports
174
185
  `Reviewed N of M changed files` instead of claiming completeness. Fan-out
175
186
  capacity overflow is reported in the review summary, never dropped. Any
176
187
  blocking active finding fails the Action check. Any required-file coverage
177
- gap — undiffable/unassigned paths, failed units (including policy exhaustion),
178
- truncation, or coordinator/run failure is non-success rather than green.
188
+ gap — paths with neither a patch nor bounded textual fallback, unassigned
189
+ paths, failed units (including policy exhaustion), truncation, or
190
+ coordinator/run failure — is non-success rather than green.
package/dist/action.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dn as PullRequestSource, Dt as ReviewStateAuthenticator, En as PullRequestMetadata, G as GitHubApiFailure, J as PriorReviews, On as PullRequestSourceFailure, St as ReviewMode, X as ReviewPublisher, jn as ChangedFile, st as ReviewRetirementHost } from "./fan-out-TrA9EUCr.mjs";
1
+ import { Dn as PullRequestMetadata, Dt as ReviewStateAuthenticator, G as GitHubApiFailure, J as PriorReviews, Mn as ChangedFile, On as PullRequestSource, St as ReviewMode, X as ReviewPublisher, kn as PullRequestSourceFailure, st as ReviewRetirementHost } from "./fan-out-BiJTQrup.mjs";
2
2
  import { EffortPosition, InvalidEffortInput, ReviewProvider, ReviewRunOutcome, ReviewTargetUnresolved, RunReviewOptions } from "./index.mjs";
3
3
  import { Config, Effect, FileSystem, Schema } from "effect";
4
4
  import { BudgetExceeded } from "effect-agent";
package/dist/action.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { A as ReviewStateAuthenticator, B as selectedPullRequestSourceLayer, G as webCryptoReviewStateAuthenticatorLayer, T as ReviewHeadComparison, U as unavailableReviewStateAuthenticatorLayer, _n as normalizeRepoRelativePath, a as PriorReviews, mn as PullRequestSource, w as ReviewExecutionContext, x as retireStaleReviews, z as selectReviewRange } from "./github-5TCFrxfX.mjs";
2
- import { A as InvalidEffortInput, M as parseEffortPosition, a as anthropicClientLayer, b as fanOutReviewBudgetLimits, c as makeOpenAiReviewModel, f as gitHubReviewLayers, h as PrReview, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, p as readGitHubEvent, s as makeAnthropicReviewModel, x as reviewBudgetLimits } from "./providers-DobNWMUn.mjs";
1
+ import { A as ReviewStateAuthenticator, B as selectedPullRequestSourceLayer, G as webCryptoReviewStateAuthenticatorLayer, T as ReviewHeadComparison, U as unavailableReviewStateAuthenticatorLayer, a as PriorReviews, hn as PullRequestSource, vn as normalizeRepoRelativePath, w as ReviewExecutionContext, x as retireStaleReviews, z as selectReviewRange } from "./github-CnGU7FFJ.mjs";
2
+ import { A as InvalidEffortInput, M as parseEffortPosition, a as anthropicClientLayer, b as fanOutReviewBudgetLimits, c as makeOpenAiReviewModel, f as gitHubReviewLayers, h as PrReview, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, p as readGitHubEvent, s as makeAnthropicReviewModel, x as reviewBudgetLimits } from "./providers-C6RkwIAJ.mjs";
3
3
  import { Config, Console, Effect, FileSystem, Layer, Option, Redacted, Schema } from "effect";
4
4
  import { BudgetExceeded, UsageBudgetLimits } from "effect-agent";
5
5
  import { FetchHttpClient } from "effect/unstable/http";
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { c as fingerprintUnchanged } from "./github-5TCFrxfX.mjs";
2
- import { A as InvalidEffortInput, M as parseEffortPosition, a as anthropicClientLayer, c as makeOpenAiReviewModel, f as gitHubReviewLayers, h as PrReview, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, s as makeAnthropicReviewModel, t as DEFAULT_MODEL, w as ReviewPublicationPlan } from "./providers-DobNWMUn.mjs";
1
+ import { c as fingerprintUnchanged } from "./github-CnGU7FFJ.mjs";
2
+ import { A as InvalidEffortInput, M as parseEffortPosition, a as anthropicClientLayer, c as makeOpenAiReviewModel, f as gitHubReviewLayers, h as PrReview, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, s as makeAnthropicReviewModel, t as DEFAULT_MODEL, w as ReviewPublicationPlan } from "./providers-C6RkwIAJ.mjs";
3
3
  import { Console, Effect, Layer, Option, Schema } from "effect";
4
4
  import { BudgetExceeded } from "effect-agent";
5
5
  import { FetchHttpClient } from "effect/unstable/http";
@@ -16,9 +16,30 @@ declare const ChangedFile_base: Schema.Class<ChangedFile, Schema.Struct<{
16
16
  readonly previousPath: Schema.optionalKey<Schema.NonEmptyString>;
17
17
  /** Unified-diff hunks; absent for binary or oversized files. */
18
18
  readonly patch: Schema.optionalKey<Schema.String>;
19
+ /**
20
+ * Bounded UTF-8 content used only when the provider omitted `patch`.
21
+ * Modified files require both sides; additions require head content and
22
+ * deletions require base content. These values are review evidence, never
23
+ * GitHub inline-comment anchors.
24
+ */
25
+ readonly reviewBaseContent: Schema.optionalKey<Schema.String>;
26
+ readonly reviewHeadContent: Schema.optionalKey<Schema.String>;
19
27
  }>, {}>;
20
28
  /** One file changed by the pull request, with its optional textual patch. */
21
29
  declare class ChangedFile extends ChangedFile_base {}
30
+ /** Complete rendered fallback evidence must fit one ordinary model context. */
31
+ declare const MAX_REVIEW_CONTENT_CHARS = 220000;
32
+ /**
33
+ * Render complete patchless evidence, or refuse it when a required side is
34
+ * absent or B/H annotation would exceed the model-facing bound. Callers use
35
+ * this same value for planning and tool output so truncated fallback evidence
36
+ * can never count as complete coverage.
37
+ */
38
+ declare const renderReviewContent: (file: ChangedFile) => string | undefined;
39
+ /** Whether complete patchless evidence fits the model-facing review bound. */
40
+ declare const hasReviewableContent: (file: ChangedFile) => boolean;
41
+ /** Whether the reviewer has either a real patch or bounded textual fallback evidence. */
42
+ declare const isReviewableFile: (file: ChangedFile) => boolean;
22
43
  /** One parsed line of a unified diff, with both coordinate systems. */
23
44
  interface PatchLine {
24
45
  readonly kind: "context" | "add" | "del";
@@ -136,12 +157,16 @@ declare const assessReviewCoverage: (input: {
136
157
  declare const MAX_FINDINGS = 20;
137
158
  /** The hard non-anchored-concerns bound carried by the CodeReview schema. */
138
159
  declare const MAX_CONCERNS = 10;
160
+ /** The encoded Tool result must retain one complete bounded content fallback. */
161
+ declare const REVIEW_TOOL_RESULT_MAX_BYTES: number;
139
162
  declare const ChangedFileSummary_base: Schema.Class<ChangedFileSummary, Schema.Struct<{
140
163
  readonly path: Schema.NonEmptyString;
141
164
  readonly status: Schema.Literals<readonly ["added", "removed", "modified", "renamed", "copied", "changed", "unchanged"]>;
142
165
  readonly additions: Schema.Int;
143
166
  readonly deletions: Schema.Int;
144
167
  readonly hasTextualDiff: Schema.Boolean;
168
+ /** True when a missing patch was recovered as bounded UTF-8 base/head content. */
169
+ readonly hasReviewableContent: Schema.Boolean;
145
170
  }>, {}>;
146
171
  declare class ChangedFileSummary extends ChangedFileSummary_base {}
147
172
  declare const ChangedFilesView_base: Schema.Class<ChangedFilesView, Schema.Struct<{
@@ -169,10 +194,13 @@ declare class FileDiffQuery extends FileDiffQuery_base {}
169
194
  declare const FileDiffView_base: Schema.Class<FileDiffView, Schema.Struct<{
170
195
  readonly path: Schema.NonEmptyString;
171
196
  readonly status: Schema.Literals<readonly ["added", "removed", "modified", "renamed", "copied", "changed", "unchanged"]>;
197
+ readonly reviewMode: Schema.Literals<readonly ["diff", "content", "unavailable"]>;
172
198
  /**
173
199
  * The unified diff with explicit RIGHT-side line numbers: `R<n>` marks a
174
200
  * line present in the new file version (only those may anchor findings);
175
- * `-` marks removed lines. Empty when no textual diff exists.
201
+ * `-` marks removed lines. For content fallback, `B<n>` and `H<n>`
202
+ * identify base/head lines for reading only; they are never valid anchors.
203
+ * Empty only when neither a patch nor bounded textual content exists.
176
204
  */
177
205
  readonly annotatedPatch: Schema.String;
178
206
  readonly truncated: Schema.Boolean;
@@ -739,7 +767,7 @@ declare const ReviewUnitPlan_base: Schema.Class<ReviewUnitPlan, Schema.Struct<{
739
767
  /** True when the source returned fewer files than the pull request has. */
740
768
  readonly truncated: Schema.Boolean;
741
769
  readonly units: Schema.$Array<typeof ReviewUnit>;
742
- /** Changed files without a textual diff; no finding can anchor to them. */
770
+ /** Changed files with neither a textual diff nor bounded base/head text. */
743
771
  readonly undiffablePaths: Schema.$Array<Schema.NonEmptyString>;
744
772
  /**
745
773
  * Diffable files beyond the fan-out capacity (MAX_REVIEW_UNITS units of
@@ -758,10 +786,12 @@ declare class ReviewUnitPlan extends ReviewUnitPlan_base {}
758
786
  * then packed greedily in that order under the soft changed-line budget and
759
787
  * the hard per-unit file bound. Capacity is finite and explicit:
760
788
  *
761
- * - files without a textual diff are not delegated no finding can anchor
762
- * to them (anchor validation demands a parsed patch), so they surface in
763
- * `undiffablePaths` instead of consuming a child's budget;
764
- * - diffable files beyond `MAX_REVIEW_UNITS` full units surface in
789
+ * - files without a textual diff are still delegated when the source
790
+ * recovered complete bounded UTF-8 base/head content. Findings from that
791
+ * evidence cannot anchor inline and are reported as concerns;
792
+ * - files with neither form of textual evidence surface in
793
+ * `undiffablePaths` instead of laundering missing coverage;
794
+ * - reviewable files beyond `MAX_REVIEW_UNITS` full units surface in
765
795
  * `unassignedPaths` so the review can report them as unreviewed, never
766
796
  * silently truncated.
767
797
  */
@@ -1081,5 +1111,5 @@ declare const fanOutHandlersLayer: <Provider, ModelProvides, ModelRequires>(chil
1081
1111
  readonly message?: string;
1082
1112
  }, never>>;
1083
1113
  //#endregion
1084
- export { gitHubPullRequestSourceLayer as $, MAX_CONCERNS as $t, fileReviewerInstructions as A, normalizeRepoRelativePath as An, StoredReviewConcern as At, ReviewUnitPlan as B, unavailableReviewStateAuthenticatorLayer as Bt, defaultFanOutPolicy as C, assessReviewCoverage as Cn, ReviewScopeMode as Ct, fanOutReviewInstructions as D, PullRequestSource as Dn, ReviewStateAuthenticator as Dt, fanOutHandlersLayerFor as E, PullRequestMetadata as En, ReviewStateAuthenticationFailure as Et, MAX_MERGED_FINDINGS as F, annotatePatch as Fn, fromStoredFinding as Ft, GitHubApiFailure as G, CodeReview as Gt, planReviewUnits as H, webCryptoReviewStateAuthenticatorLayer as Ht, MAX_REVIEW_UNITS as I, commentableLines as In, selectReviewRange as It, PriorReviews as J, FileSlice as Jt, GitHubReviewTarget as K, FileDiffQuery as Kt, MAX_UNIT_FILES as L, parsePatch as Ln, selectedPullRequestSourceLayer as Lt, makeFanOutReviewSuite as M, ChangedFileStatus as Mn, buildProfileMission as Mt, makeFileReviewerInstructions as N, ChangedPath as Nn, computeProfileFingerprint as Nt, fileReviewDelegation as O, PullRequestSourceFailure as On, ReviewStateMarker as Ot, mapFileReviewChildFailure as P, PatchLine as Pn, fromStoredConcern as Pt, gitHubPriorReviewsLayer as Q, ListChangedFilesQuery as Qt, ReviewUnit as R, toStoredConcern as Rt, MAX_FILE_REVIEW_TOOL_CALLS as S, ReviewShape as Sn, ReviewMode as St, fanOutHandlersLayer as T, MAX_FILE_CHARS as Tn, ReviewState as Tt, rankAndDedupeFindings as U, ChangedFileSummary as Ut, UNIT_CHANGED_LINE_BUDGET as V, validateReviewState as Vt, DEFAULT_GITHUB_REVIEW_AUTHOR_LOGIN as W, ChangedFilesView as Wt, ReviewPublisher as X, FindingSeverity as Xt, PublishedReview as Y, FileSliceQuery as Yt, fingerprintUnchanged as Z, ListChangedFiles as Zt, FileReviewer as _, readFileHandler as _n, planPublication as _t, FanOutReviewSuite as a, ReviewFinding as an, ReviewRetirementDecision as at, MAX_CHILD_CONCERNS as b, FailedReviewUnit as bn, ReviewExecutionContext as bt, FanOutSuiteOptions as c, ReviewMission as cn, ReviewRetirementInput as ct, FileReviewReport as d, ReviewVerdict as dn, hasReviewMetadataMarker as dt, MAX_FINDINGS as en, gitHubReviewPublisherLayer as et, FileReviewRequest as f, clampMaxFindings as fn, retireStaleReviews as ft, FileReviewUnitResult as g, readFileDiffHandler as gn, anchorViolation as gt, FileReviewUnitFailed as h, makeReviewInstructions as hn, ReviewPublicationPlan as ht, FanOutInstructionOptions as i, ReviewConcern as in, RetirableReviewComment as it, makeFanOutReviewInstructions as j, ChangedFile as jn, StoredReviewFinding as jt, fileReviewPolicy as k, ReviewInputViolation as kn, ReviewStateMarkerTooLarge as kt, FileReviewBrief as l, ReviewToolkit as ln, ReviewRetirementReport as lt, FileReviewToolkitLayer as m, listChangedFilesHandler as mn, ReviewEvent as mt, FanOutCoordinatorToolkit as n, ReadFile as nn, parseGitHubSubmittedAt as nt, FanOutReviewToolkit as o, ReviewGuidance as on, ReviewRetirementFailure as ot, FileReviewToolkit as p, defaultReviewPolicy as pn, ReviewCommentDraft as pt, PriorReviewLookupFailure as q, FileDiffView as qt, FanOutCoordinatorToolkitLayer as r, ReadFileDiff as rn, RetirableReview as rt, FanOutReviewer as s, ReviewInstructionOptions as sn, ReviewRetirementHost as st, DelegateFileReview as t, PullRequestReviewer as tn, gitHubReviewRetirementHostLayer as tt, FileReviewDelegationFailure as u, ReviewToolkitLayer as un, decideReviewRetirement as ut, ListReviewUnits as v, resolveGuidance as vn, GitCommitSha as vt, defaultFileReviewerPolicy as w, MAX_CHANGED_FILES as wn, ReviewSelection as wt, MAX_CHILD_FINDINGS as x, ReviewCoverage as xn, ReviewHeadComparison as xt, ListReviewUnitsQuery as y, reviewInstructions as yn, MAX_REVIEW_STATE_MARKER_CHARS as yt, ReviewUnitId as z, toStoredFinding as zt };
1085
- //# sourceMappingURL=fan-out-TrA9EUCr.d.mts.map
1114
+ export { gitHubPullRequestSourceLayer as $, MAX_CONCERNS as $t, fileReviewerInstructions as A, ReviewInputViolation as An, StoredReviewConcern as At, ReviewUnitPlan as B, isReviewableFile as Bn, unavailableReviewStateAuthenticatorLayer as Bt, defaultFanOutPolicy as C, ReviewShape as Cn, ReviewScopeMode as Ct, fanOutReviewInstructions as D, PullRequestMetadata as Dn, ReviewStateAuthenticator as Dt, fanOutHandlersLayerFor as E, MAX_FILE_CHARS as En, ReviewStateAuthenticationFailure as Et, MAX_MERGED_FINDINGS as F, MAX_REVIEW_CONTENT_CHARS as Fn, fromStoredFinding as Ft, GitHubApiFailure as G, CodeReview as Gt, planReviewUnits as H, renderReviewContent as Hn, webCryptoReviewStateAuthenticatorLayer as Ht, MAX_REVIEW_UNITS as I, PatchLine as In, selectReviewRange as It, PriorReviews as J, FileSlice as Jt, GitHubReviewTarget as K, FileDiffQuery as Kt, MAX_UNIT_FILES as L, annotatePatch as Ln, selectedPullRequestSourceLayer as Lt, makeFanOutReviewSuite as M, ChangedFile as Mn, buildProfileMission as Mt, makeFileReviewerInstructions as N, ChangedFileStatus as Nn, computeProfileFingerprint as Nt, fileReviewDelegation as O, PullRequestSource as On, ReviewStateMarker as Ot, mapFileReviewChildFailure as P, ChangedPath as Pn, fromStoredConcern as Pt, gitHubPriorReviewsLayer as Q, ListChangedFilesQuery as Qt, ReviewUnit as R, commentableLines as Rn, toStoredConcern as Rt, MAX_FILE_REVIEW_TOOL_CALLS as S, ReviewCoverage as Sn, ReviewMode as St, fanOutHandlersLayer as T, MAX_CHANGED_FILES as Tn, ReviewState as Tt, rankAndDedupeFindings as U, ChangedFileSummary as Ut, UNIT_CHANGED_LINE_BUDGET as V, parsePatch as Vn, validateReviewState as Vt, DEFAULT_GITHUB_REVIEW_AUTHOR_LOGIN as W, ChangedFilesView as Wt, ReviewPublisher as X, FindingSeverity as Xt, PublishedReview as Y, FileSliceQuery as Yt, fingerprintUnchanged as Z, ListChangedFiles as Zt, FileReviewer as _, readFileDiffHandler as _n, planPublication as _t, FanOutReviewSuite as a, ReviewConcern as an, ReviewRetirementDecision as at, MAX_CHILD_CONCERNS as b, reviewInstructions as bn, ReviewExecutionContext as bt, FanOutSuiteOptions as c, ReviewInstructionOptions as cn, ReviewRetirementInput as ct, FileReviewReport as d, ReviewToolkitLayer as dn, hasReviewMetadataMarker as dt, MAX_FINDINGS as en, gitHubReviewPublisherLayer as et, FileReviewRequest as f, ReviewVerdict as fn, retireStaleReviews as ft, FileReviewUnitResult as g, makeReviewInstructions as gn, anchorViolation as gt, FileReviewUnitFailed as h, listChangedFilesHandler as hn, ReviewPublicationPlan as ht, FanOutInstructionOptions as i, ReadFileDiff as in, RetirableReviewComment as it, makeFanOutReviewInstructions as j, normalizeRepoRelativePath as jn, StoredReviewFinding as jt, fileReviewPolicy as k, PullRequestSourceFailure as kn, ReviewStateMarkerTooLarge as kt, FileReviewBrief as l, ReviewMission as ln, ReviewRetirementReport as lt, FileReviewToolkitLayer as m, defaultReviewPolicy as mn, ReviewEvent as mt, FanOutCoordinatorToolkit as n, REVIEW_TOOL_RESULT_MAX_BYTES as nn, parseGitHubSubmittedAt as nt, FanOutReviewToolkit as o, ReviewFinding as on, ReviewRetirementFailure as ot, FileReviewToolkit as p, clampMaxFindings as pn, ReviewCommentDraft as pt, PriorReviewLookupFailure as q, FileDiffView as qt, FanOutCoordinatorToolkitLayer as r, ReadFile as rn, RetirableReview as rt, FanOutReviewer as s, ReviewGuidance as sn, ReviewRetirementHost as st, DelegateFileReview as t, PullRequestReviewer as tn, gitHubReviewRetirementHostLayer as tt, FileReviewDelegationFailure as u, ReviewToolkit as un, decideReviewRetirement as ut, ListReviewUnits as v, readFileHandler as vn, GitCommitSha as vt, defaultFileReviewerPolicy as w, assessReviewCoverage as wn, ReviewSelection as wt, MAX_CHILD_FINDINGS as x, FailedReviewUnit as xn, ReviewHeadComparison as xt, ListReviewUnitsQuery as y, resolveGuidance as yn, MAX_REVIEW_STATE_MARKER_CHARS as yt, ReviewUnitId as z, hasReviewableContent as zn, toStoredFinding as zt };
1115
+ //# sourceMappingURL=fan-out-BiJTQrup.d.mts.map
@@ -1,5 +1,5 @@
1
1
  import { Context, DateTime, Effect, Encoding, Layer, Option, Redacted, Result, Schema } from "effect";
2
- import { Agent, AgentPolicy, Subagent, SubagentPolicy, SubagentRuntime, ToolExecutionClass } from "effect-agent";
2
+ import { Agent, AgentPolicy, Subagent, SubagentPolicy, SubagentRuntime, ToolExecutionClass, ToolResultBounds } from "effect-agent";
3
3
  import { Tool, Toolkit } from "effect/unstable/ai";
4
4
  import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http";
5
5
  //#region src/internal/diff.ts
@@ -24,8 +24,57 @@ var ChangedFile = class extends Schema.Class("@effect-agent/pr-review/ChangedFil
24
24
  /** Present for renames/copies: the path the file previously had. */
25
25
  previousPath: Schema.optionalKey(ChangedPath),
26
26
  /** Unified-diff hunks; absent for binary or oversized files. */
27
- patch: Schema.optionalKey(Schema.String)
27
+ patch: Schema.optionalKey(Schema.String),
28
+ /**
29
+ * Bounded UTF-8 content used only when the provider omitted `patch`.
30
+ * Modified files require both sides; additions require head content and
31
+ * deletions require base content. These values are review evidence, never
32
+ * GitHub inline-comment anchors.
33
+ */
34
+ reviewBaseContent: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2e5))),
35
+ reviewHeadContent: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2e5)))
28
36
  }) {};
37
+ /** Complete rendered fallback evidence must fit one ordinary model context. */
38
+ const MAX_REVIEW_CONTENT_CHARS = 22e4;
39
+ /**
40
+ * Render complete patchless evidence, or refuse it when a required side is
41
+ * absent or B/H annotation would exceed the model-facing bound. Callers use
42
+ * this same value for planning and tool output so truncated fallback evidence
43
+ * can never count as complete coverage.
44
+ */
45
+ const renderReviewContent = (file) => {
46
+ if (file.patch !== void 0) return void 0;
47
+ const includeBase = file.status !== "added";
48
+ const includeHead = file.status !== "removed";
49
+ const sections = ["[GitHub omitted the unified diff. B/H lines below are bounded full-file review content, not valid inline-comment anchors. Report defects from this evidence as non-anchored concerns.]"];
50
+ let renderedLength = sections[0]?.length ?? 0;
51
+ const append = (part) => {
52
+ const nextLength = renderedLength + 1 + part.length;
53
+ if (nextLength > 22e4) return false;
54
+ sections.push(part);
55
+ renderedLength = nextLength;
56
+ return true;
57
+ };
58
+ const appendSide = (side, header, content) => {
59
+ if (!append(header)) return false;
60
+ const lines = content.split("\n");
61
+ for (let index = 0; index < lines.length; index += 1) if (!append(`${side}${index + 1} ${lines[index] ?? ""}`)) return false;
62
+ return true;
63
+ };
64
+ if (includeBase) {
65
+ if (file.reviewBaseContent === void 0) return void 0;
66
+ if (!appendSide("B", "[BASE VERSION]", file.reviewBaseContent)) return void 0;
67
+ }
68
+ if (includeHead) {
69
+ if (file.reviewHeadContent === void 0) return void 0;
70
+ if (!appendSide("H", "[HEAD VERSION]", file.reviewHeadContent)) return void 0;
71
+ }
72
+ return sections.join("\n");
73
+ };
74
+ /** Whether complete patchless evidence fits the model-facing review bound. */
75
+ const hasReviewableContent = (file) => renderReviewContent(file) !== void 0;
76
+ /** Whether the reviewer has either a real patch or bounded textual fallback evidence. */
77
+ const isReviewableFile = (file) => file.patch !== void 0 || hasReviewableContent(file);
29
78
  const HUNK_HEADER = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
30
79
  /**
31
80
  * Parse unified-diff hunk text into coordinate-tagged lines. Lines outside a
@@ -188,6 +237,8 @@ const MAX_FINDINGS = 20;
188
237
  const MAX_CONCERNS = 10;
189
238
  /** Annotated patches larger than this are truncated with an explicit marker. */
190
239
  const MAX_PATCH_CHARS = 6e4;
240
+ /** The encoded Tool result must retain one complete bounded content fallback. */
241
+ const REVIEW_TOOL_RESULT_MAX_BYTES = 2 * 1024 * 1024;
191
242
  /** One `read_file` slice never exceeds this many lines. */
192
243
  const MAX_SLICE_LINES = 1e3;
193
244
  const DEFAULT_SLICE_LINES = 400;
@@ -196,7 +247,9 @@ var ChangedFileSummary = class extends Schema.Class("@effect-agent/pr-review/Cha
196
247
  status: ChangedFileStatus,
197
248
  additions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
198
249
  deletions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
199
- hasTextualDiff: Schema.Boolean
250
+ hasTextualDiff: Schema.Boolean,
251
+ /** True when a missing patch was recovered as bounded UTF-8 base/head content. */
252
+ hasReviewableContent: Schema.Boolean
200
253
  }) {};
201
254
  var ChangedFilesView = class extends Schema.Class("@effect-agent/pr-review/ChangedFilesView")({
202
255
  totalFiles: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
@@ -219,16 +272,23 @@ var FileDiffQuery = class extends Schema.Class("@effect-agent/pr-review/FileDiff
219
272
  var FileDiffView = class extends Schema.Class("@effect-agent/pr-review/FileDiffView")({
220
273
  path: ChangedPath,
221
274
  status: ChangedFileStatus,
275
+ reviewMode: Schema.Literals([
276
+ "diff",
277
+ "content",
278
+ "unavailable"
279
+ ]),
222
280
  /**
223
281
  * The unified diff with explicit RIGHT-side line numbers: `R<n>` marks a
224
282
  * line present in the new file version (only those may anchor findings);
225
- * `-` marks removed lines. Empty when no textual diff exists.
283
+ * `-` marks removed lines. For content fallback, `B<n>` and `H<n>`
284
+ * identify base/head lines for reading only; they are never valid anchors.
285
+ * Empty only when neither a patch nor bounded textual content exists.
226
286
  */
227
287
  annotatedPatch: Schema.String,
228
288
  truncated: Schema.Boolean
229
289
  }) {};
230
290
  const ReadFileDiff = Tool.make("read_file_diff", {
231
- description: "Read the annotated unified diff of one changed file. Lines marked R<number> exist in the new version and are the only valid finding anchors.",
291
+ description: "Read one changed file's review evidence. A normal unified diff marks valid anchors as R<number>. When GitHub omitted the diff, bounded base/head content is returned with B/H line labels for review but no valid inline anchors.",
232
292
  parameters: FileDiffQuery,
233
293
  success: FileDiffView,
234
294
  failure: Schema.Union([PullRequestSourceFailure, ReviewInputViolation]),
@@ -275,7 +335,8 @@ const listChangedFilesHandler = (_query) => Effect.gen(function* () {
275
335
  status: file.status,
276
336
  additions: file.additions,
277
337
  deletions: file.deletions,
278
- hasTextualDiff: file.patch !== void 0
338
+ hasTextualDiff: file.patch !== void 0,
339
+ hasReviewableContent: hasReviewableContent(file)
279
340
  }))
280
341
  });
281
342
  });
@@ -291,11 +352,14 @@ const readFileDiffHandler = (query) => Effect.gen(function* () {
291
352
  input: relative,
292
353
  reason: "Path is not part of this pull request's changeset."
293
354
  });
294
- const annotated = file.patch === void 0 ? "" : annotatePatch(file.patch);
295
- const truncated = annotated.length > MAX_PATCH_CHARS;
355
+ const contentEvidence = renderReviewContent(file);
356
+ const reviewMode = file.patch !== void 0 ? "diff" : contentEvidence !== void 0 ? "content" : "unavailable";
357
+ const annotated = file.patch === void 0 ? contentEvidence ?? "" : annotatePatch(file.patch);
358
+ const truncated = reviewMode === "diff" && annotated.length > MAX_PATCH_CHARS;
296
359
  return FileDiffView.make({
297
360
  path: file.path,
298
361
  status: file.status,
362
+ reviewMode,
299
363
  annotatedPatch: truncated ? `${annotated.slice(0, MAX_PATCH_CHARS)}\n[diff truncated]` : annotated,
300
364
  truncated
301
365
  });
@@ -394,7 +458,7 @@ const makeReviewInstructions = (options = {}) => (mission) => {
394
458
  ...resolveGuidance(options.guidance, mission),
395
459
  "Work in this order:",
396
460
  "1. Call list_changed_files once to see the changeset.",
397
- "2. Call read_file_diff for every file you review. In its output, only lines marked R<number> exist in the new version; those numbers are the only valid values for startLine and endLine. Never anchor a finding to a removed (-) line.",
461
+ "2. Call read_file_diff for every file you review. A normal diff marks new-version anchors as R<number>; only those numbers are valid startLine/endLine values. When GitHub omitted a diff, the tool may return bounded base/head content marked B/H instead. Review that content, but report its defects as non-anchored concerns because B/H lines cannot anchor GitHub comments. Never anchor a finding to a removed (-), B, or H line.",
398
462
  "3. Call read_file when you need surrounding context the diff does not show. ONLY files in the changeset are readable: a request for any other path (an import, a neighbor, a config) returns a failed result — do not retry it; reason from the diff instead and note the gap honestly in your summary when it matters.",
399
463
  "4. Review for real defects first: correctness, security, concurrency, resource leaks, error handling, API misuse. Style nits are least important. Do not praise; do not restate the diff.",
400
464
  "When the diff adds or changes a test, check that it can actually fail: a test that would still pass with the bug present is theatre, not coverage. The usual tell is a loose assertion standing where an exact one belongs — >= or a truthiness check over an expected value, or a snapshot that absorbs whatever it is handed.",
@@ -416,6 +480,7 @@ const defaultReviewPolicy = AgentPolicy.make({
416
480
  toolConcurrency: 2,
417
481
  tokenBudget: 3e5,
418
482
  contextTokenLimit: 15e4,
483
+ toolResultBounds: ToolResultBounds.make({ maxBytes: REVIEW_TOOL_RESULT_MAX_BYTES }),
419
484
  onExhaustion: "final-answer"
420
485
  });
421
486
  const PullRequestReviewer = Agent.define("pr-reviewer", {
@@ -456,7 +521,7 @@ var ReviewUnitPlan = class extends Schema.Class("@effect-agent/pr-review/ReviewU
456
521
  /** True when the source returned fewer files than the pull request has. */
457
522
  truncated: Schema.Boolean,
458
523
  units: Schema.Array(ReviewUnit).check(Schema.isMaxLength(8)),
459
- /** Changed files without a textual diff; no finding can anchor to them. */
524
+ /** Changed files with neither a textual diff nor bounded base/head text. */
460
525
  undiffablePaths: Schema.Array(ChangedPath).check(Schema.isMaxLength(300)),
461
526
  /**
462
527
  * Diffable files beyond the fan-out capacity (MAX_REVIEW_UNITS units of
@@ -465,7 +530,11 @@ var ReviewUnitPlan = class extends Schema.Class("@effect-agent/pr-review/ReviewU
465
530
  */
466
531
  unassignedPaths: Schema.Array(ChangedPath).check(Schema.isMaxLength(300))
467
532
  }) {};
468
- const fileCost = (file) => file.additions + file.deletions + FILE_OVERHEAD_LINES;
533
+ const fileCost = (file) => {
534
+ const contentChars = (file.reviewBaseContent?.length ?? 0) + (file.reviewHeadContent?.length ?? 0);
535
+ const contentWeight = Math.ceil(contentChars / 200);
536
+ return file.additions + file.deletions + contentWeight + FILE_OVERHEAD_LINES;
537
+ };
469
538
  const unitOf = (index, files) => ReviewUnit.make({
470
539
  unitId: `unit-${String(index + 1).padStart(3, "0")}`,
471
540
  paths: files.map((file) => file.path),
@@ -479,22 +548,24 @@ const unitOf = (index, files) => ReviewUnit.make({
479
548
  * then packed greedily in that order under the soft changed-line budget and
480
549
  * the hard per-unit file bound. Capacity is finite and explicit:
481
550
  *
482
- * - files without a textual diff are not delegated no finding can anchor
483
- * to them (anchor validation demands a parsed patch), so they surface in
484
- * `undiffablePaths` instead of consuming a child's budget;
485
- * - diffable files beyond `MAX_REVIEW_UNITS` full units surface in
551
+ * - files without a textual diff are still delegated when the source
552
+ * recovered complete bounded UTF-8 base/head content. Findings from that
553
+ * evidence cannot anchor inline and are reported as concerns;
554
+ * - files with neither form of textual evidence surface in
555
+ * `undiffablePaths` instead of laundering missing coverage;
556
+ * - reviewable files beyond `MAX_REVIEW_UNITS` full units surface in
486
557
  * `unassignedPaths` so the review can report them as unreviewed, never
487
558
  * silently truncated.
488
559
  */
489
560
  const planReviewUnits = (files, options) => {
490
561
  const ordered = [...files].sort((left, right) => left.path < right.path ? -1 : 1);
491
- const diffable = ordered.filter((file) => file.patch !== void 0);
492
- const undiffable = ordered.filter((file) => file.patch === void 0);
562
+ const reviewable = ordered.filter(isReviewableFile);
563
+ const undiffable = ordered.filter((file) => !isReviewableFile(file));
493
564
  const groups = [];
494
565
  const unassigned = [];
495
566
  let current = [];
496
567
  let currentCost = 0;
497
- for (const file of diffable) {
568
+ for (const file of reviewable) {
498
569
  const cost = fileCost(file);
499
570
  if (current.length >= 12 || current.length > 0 && currentCost + cost > 800) {
500
571
  groups.push(current);
@@ -584,7 +655,7 @@ const makeFileReviewerInstructions = (options = {}) => (brief) => [
584
655
  `You are a code reviewer for one unit of a pull request: unit ${brief.unitId}, covering exactly these changed files: ${brief.paths.join(", ")}. Focus: ${brief.focus}.`,
585
656
  ...staticGuidanceLines(options.guidance),
586
657
  "Work in this order:",
587
- "1. Call read_file_diff for every file in your unit. In its output, only lines marked R<number> exist in the new version; those numbers are the only valid values for startLine and endLine. Never anchor a finding to a removed (-) line.",
658
+ "1. Call read_file_diff for every file in your unit. A normal diff marks new-version anchors as R<number>; only those numbers are valid startLine/endLine values. When GitHub omitted a diff, the tool may return bounded base/head content marked B/H instead. Review that content, but report its defects as non-anchored concerns because B/H lines cannot anchor GitHub comments. Never anchor a finding to a removed (-), B, or H line.",
588
659
  "2. Call read_file when you need surrounding context the diff does not show. ONLY files in the changeset are readable: a request for any other path (an import, a neighbor, a config) returns a failed result — do not retry it; reason from the diff instead and note the gap in your report when it matters.",
589
660
  "3. Review for real defects first: correctness, security, concurrency, resource leaks, error handling, API misuse. Style nits are least important. Do not praise; do not restate the diff.",
590
661
  "When the diff adds or changes a test, check that it can actually fail: a test that would still pass with the bug present is theatre, not coverage. The usual tell is a loose assertion standing where an exact one belongs — >= or a truthiness check over an expected value, or a snapshot that absorbs whatever it is handed.",
@@ -601,6 +672,7 @@ const defaultFileReviewerPolicy = AgentPolicy.make({
601
672
  toolConcurrency: 2,
602
673
  tokenBudget: 2e5,
603
674
  contextTokenLimit: 15e4,
675
+ toolResultBounds: ToolResultBounds.make({ maxBytes: REVIEW_TOOL_RESULT_MAX_BYTES }),
604
676
  onExhaustion: "fail"
605
677
  });
606
678
  /** The model-decoded delegation parameters: which unit to review. */
@@ -805,7 +877,7 @@ const SECTION = "";
805
877
  * Canonical changeset encoding: sorted by path so provider ordering never
806
878
  * matters, with every review-relevant field of every file.
807
879
  */
808
- const canonicalChangeset = (files) => files.map((file) => `${file.path}${FIELD}${file.status}${FIELD}${String(file.additions)}${FIELD}${String(file.deletions)}${FIELD}${file.patch ?? ""}`).sort().join(RECORD);
880
+ const canonicalChangeset = (files) => files.map((file) => `${file.path}${FIELD}${file.status}${FIELD}${String(file.additions)}${FIELD}${String(file.deletions)}${FIELD}${file.patch ?? ""}${FIELD}${file.reviewBaseContent ?? ""}${FIELD}${file.reviewHeadContent ?? ""}`).sort().join(RECORD);
809
881
  /**
810
882
  * Fingerprint one review's complete input surface: the (already
811
883
  * ignore-filtered) changeset plus the caller's prompt signature — the
@@ -1068,9 +1140,21 @@ var ReviewExecutionContext = class extends Context.Service()("@effect-agent/pr-r
1068
1140
  const selectedPullRequestSourceLayer = (selection) => Layer.effect(PullRequestSource)(Effect.gen(function* () {
1069
1141
  const source = yield* PullRequestSource;
1070
1142
  const selectedPaths = new Set(selection.files.map((file) => file.path));
1143
+ const selectedFiles = source.changedFiles.pipe(Effect.map((fullFiles) => {
1144
+ const fullByPath = new Map(fullFiles.map((file) => [file.path, file]));
1145
+ return selection.files.map((file) => {
1146
+ if (file.patch !== void 0) return file;
1147
+ const full = fullByPath.get(file.path);
1148
+ return full === void 0 ? file : ChangedFile.make({
1149
+ ...file,
1150
+ ...full.reviewBaseContent === void 0 ? {} : { reviewBaseContent: full.reviewBaseContent },
1151
+ ...full.reviewHeadContent === void 0 ? {} : { reviewHeadContent: full.reviewHeadContent }
1152
+ });
1153
+ });
1154
+ }));
1071
1155
  return PullRequestSource.of({
1072
1156
  metadata: source.metadata,
1073
- changedFiles: Effect.succeed(selection.files),
1157
+ changedFiles: selectedFiles,
1074
1158
  anchorFiles: source.anchorFiles,
1075
1159
  readFile: (path) => selectedPaths.has(path) ? source.readFile(path) : Effect.fail(ReviewInputViolation.make({
1076
1160
  input: path,
@@ -1437,22 +1521,60 @@ const gitHubPullRequestSourceLayer = Layer.effect(PullRequestSource)(Effect.gen(
1437
1521
  return all;
1438
1522
  });
1439
1523
  const metadata = yield* Effect.cached(fetchMetadata.pipe(Effect.provideService(HttpClient.HttpClient, client)));
1440
- const changedFiles = yield* Effect.cached(fetchFiles.pipe(Effect.provideService(HttpClient.HttpClient, client)));
1441
- const readFile = (path) => Effect.gen(function* () {
1524
+ const rawFiles = yield* Effect.cached(fetchFiles.pipe(Effect.provideService(HttpClient.HttpClient, client)));
1525
+ const readRepositoryFile = (path, ref) => Effect.gen(function* () {
1442
1526
  const relative = yield* normalizeRepoRelativePath(path);
1443
- if (!(yield* changedFiles).some((file) => file.path === relative)) return yield* ReviewInputViolation.make({
1527
+ const encodedPath = relative.split("/").map(encodeURIComponent).join("/");
1528
+ const buffer = yield* (yield* executeOk("readFile", withCommonHeaders(HttpClientRequest.get(`${target.apiUrl}/repos/${target.repository}/contents/${encodedPath}`).pipe(HttpClientRequest.accept("application/vnd.github.raw+json"), HttpClientRequest.setUrlParams({ ref })), target.token)).pipe(Effect.provideService(HttpClient.HttpClient, client))).arrayBuffer.pipe(Effect.mapError(failWith("readFile")));
1529
+ if (buffer.byteLength > 2e5) return yield* ReviewInputViolation.make({
1444
1530
  input: relative,
1445
- reason: "Path is not part of this pull request's changeset."
1531
+ reason: `File is larger than the ${MAX_FILE_CHARS}-byte read bound.`
1532
+ });
1533
+ const text = yield* Effect.try({
1534
+ try: () => new TextDecoder("utf-8", { fatal: true }).decode(buffer),
1535
+ catch: () => ReviewInputViolation.make({
1536
+ input: relative,
1537
+ reason: "File is not valid UTF-8 text."
1538
+ })
1539
+ });
1540
+ if (text.includes("\0")) return yield* ReviewInputViolation.make({
1541
+ input: relative,
1542
+ reason: "File contains binary NUL bytes."
1446
1543
  });
1447
- const head = yield* metadata;
1448
- const encodedPath = relative.split("/").map(encodeURIComponent).join("/");
1449
- const text = yield* (yield* executeOk("readFile", withCommonHeaders(HttpClientRequest.get(`${target.apiUrl}/repos/${target.repository}/contents/${encodedPath}`).pipe(HttpClientRequest.accept("application/vnd.github.raw+json"), HttpClientRequest.setUrlParams({ ref: head.headSha })), target.token)).pipe(Effect.provideService(HttpClient.HttpClient, client))).text.pipe(Effect.mapError(failWith("readFile")));
1450
1544
  if (text.length > 2e5) return yield* ReviewInputViolation.make({
1451
1545
  input: relative,
1452
1546
  reason: `File is larger than the ${MAX_FILE_CHARS}-character read bound.`
1453
1547
  });
1454
1548
  return text;
1455
1549
  });
1550
+ const changedFiles = yield* Effect.cached(Effect.gen(function* () {
1551
+ const [files, pullRequest] = yield* Effect.all([rawFiles, metadata]);
1552
+ return yield* Effect.forEach(files, (file) => {
1553
+ if (file.patch !== void 0) return Effect.succeed(file);
1554
+ const basePath = file.previousPath ?? file.path;
1555
+ const base = file.status === "added" ? Effect.succeed(Option.none()) : readRepositoryFile(basePath, pullRequest.baseSha ?? pullRequest.baseRef).pipe(Effect.option);
1556
+ const head = file.status === "removed" ? Effect.succeed(Option.none()) : readRepositoryFile(file.path, pullRequest.headSha).pipe(Effect.option);
1557
+ return Effect.all({
1558
+ base,
1559
+ head
1560
+ }).pipe(Effect.map(({ base, head }) => ChangedFile.make({
1561
+ ...file,
1562
+ ...Option.isSome(base) ? { reviewBaseContent: base.value } : {},
1563
+ ...Option.isSome(head) ? { reviewHeadContent: head.value } : {}
1564
+ })));
1565
+ }, { concurrency: 4 });
1566
+ }));
1567
+ const readFile = (path) => Effect.gen(function* () {
1568
+ const relative = yield* normalizeRepoRelativePath(path);
1569
+ const file = (yield* changedFiles).find((candidate) => candidate.path === relative);
1570
+ if (file === void 0) return yield* ReviewInputViolation.make({
1571
+ input: relative,
1572
+ reason: "Path is not part of this pull request's changeset."
1573
+ });
1574
+ if (file.reviewHeadContent !== void 0) return file.reviewHeadContent;
1575
+ const head = yield* metadata;
1576
+ return yield* readRepositoryFile(relative, head.headSha);
1577
+ });
1456
1578
  return PullRequestSource.of({
1457
1579
  metadata,
1458
1580
  changedFiles,
@@ -1671,6 +1793,6 @@ const fingerprintUnchanged = (current) => Effect.gen(function* () {
1671
1793
  return Option.isSome(latest) && latest.value === current;
1672
1794
  });
1673
1795
  //#endregion
1674
- export { FanOutReviewToolkit as $, ReviewMission as $t, ReviewStateAuthenticator as A, ReviewUnit as At, selectedPullRequestSourceLayer as B, FileDiffView as Bt, MAX_REVIEW_STATE_MARKER_CHARS as C, parsePatch as Cn, makeFanOutReviewInstructions as Ct, ReviewScopeMode as D, MAX_MERGED_FINDINGS as Dt, ReviewMode as E, mapFileReviewChildFailure as Et, buildProfileMission as F, rankAndDedupeFindings as Ft, webCryptoReviewStateAuthenticatorLayer as G, ListChangedFilesQuery as Gt, toStoredFinding as H, FileSliceQuery as Ht, computeProfileFingerprint as I, ChangedFileSummary as It, extractFingerprint as J, PullRequestReviewer as Jt, FINGERPRINT_MARKER_LENGTH as K, MAX_CONCERNS as Kt, fromStoredConcern as L, ChangedFilesView as Lt, ReviewStateMarkerTooLarge as M, ReviewUnitPlan as Mt, StoredReviewConcern as N, UNIT_CHANGED_LINE_BUDGET as Nt, ReviewState as O, MAX_REVIEW_UNITS as Ot, StoredReviewFinding as P, planReviewUnits as Pt, FanOutCoordinatorToolkitLayer as Q, ReviewFinding as Qt, fromStoredFinding as R, CodeReview as Rt, GitCommitSha as S, commentableLines as Sn, fileReviewerInstructions as St, ReviewHeadComparison as T, makeFileReviewerInstructions as Tt, unavailableReviewStateAuthenticatorLayer as U, FindingSeverity as Ut, toStoredConcern as V, FileSlice as Vt, validateReviewState as W, ListChangedFiles as Wt, DelegateFileReview as X, ReadFileDiff as Xt, renderFingerprintMarker as Y, ReadFile as Yt, FanOutCoordinatorToolkit as Z, ReviewConcern as Zt, ReviewRetirementHost as _, normalizeRepoRelativePath as _n, fanOutHandlersLayer as _t, PriorReviews as a, listChangedFilesHandler as an, FileReviewToolkit as at, hasReviewMetadataMarker as b, ChangedPath as bn, fileReviewDelegation as bt, fingerprintUnchanged as c, readFileHandler as cn, FileReviewUnitResult as ct, gitHubReviewPublisherLayer as d, MAX_CHANGED_FILES as dn, ListReviewUnitsQuery as dt, ReviewToolkit as en, FanOutReviewer as et, gitHubReviewRetirementHostLayer as f, MAX_FILE_CHARS as fn, MAX_CHILD_CONCERNS as ft, ReviewRetirementFailure as g, ReviewInputViolation as gn, defaultFileReviewerPolicy as gt, RetirableReviewComment as h, PullRequestSourceFailure as hn, defaultFanOutPolicy as ht, PriorReviewLookupFailure as i, defaultReviewPolicy as in, FileReviewRequest as it, ReviewStateMarker as j, ReviewUnitId as jt, ReviewStateAuthenticationFailure as k, MAX_UNIT_FILES as kt, gitHubPriorReviewsLayer as l, resolveGuidance as ln, FileReviewer as lt, RetirableReview as m, PullRequestSource as mn, MAX_FILE_REVIEW_TOOL_CALLS as mt, GitHubApiFailure as n, ReviewVerdict as nn, FileReviewDelegationFailure as nt, PublishedReview as o, makeReviewInstructions as on, FileReviewToolkitLayer as ot, parseGitHubSubmittedAt as p, PullRequestMetadata as pn, MAX_CHILD_FINDINGS as pt, computeChangesetFingerprint as q, MAX_FINDINGS as qt, GitHubReviewTarget as r, clampMaxFindings as rn, FileReviewReport as rt, ReviewPublisher as s, readFileDiffHandler as sn, FileReviewUnitFailed as st, DEFAULT_GITHUB_REVIEW_AUTHOR_LOGIN as t, ReviewToolkitLayer as tn, FileReviewBrief as tt, gitHubPullRequestSourceLayer as u, reviewInstructions as un, ListReviewUnits as ut, ReviewRetirementReport as v, ChangedFile as vn, fanOutHandlersLayerFor as vt, ReviewExecutionContext as w, makeFanOutReviewSuite as wt, retireStaleReviews as x, annotatePatch as xn, fileReviewPolicy as xt, decideReviewRetirement as y, ChangedFileStatus as yn, fanOutReviewInstructions as yt, selectReviewRange as z, FileDiffQuery as zt };
1796
+ export { FanOutReviewToolkit as $, ReviewFinding as $t, ReviewStateAuthenticator as A, ReviewUnit as At, selectedPullRequestSourceLayer as B, FileDiffView as Bt, MAX_REVIEW_STATE_MARKER_CHARS as C, annotatePatch as Cn, makeFanOutReviewInstructions as Ct, ReviewScopeMode as D, parsePatch as Dn, MAX_MERGED_FINDINGS as Dt, ReviewMode as E, isReviewableFile as En, mapFileReviewChildFailure as Et, buildProfileMission as F, rankAndDedupeFindings as Ft, webCryptoReviewStateAuthenticatorLayer as G, ListChangedFilesQuery as Gt, toStoredFinding as H, FileSliceQuery as Ht, computeProfileFingerprint as I, ChangedFileSummary as It, extractFingerprint as J, PullRequestReviewer as Jt, FINGERPRINT_MARKER_LENGTH as K, MAX_CONCERNS as Kt, fromStoredConcern as L, ChangedFilesView as Lt, ReviewStateMarkerTooLarge as M, ReviewUnitPlan as Mt, StoredReviewConcern as N, UNIT_CHANGED_LINE_BUDGET as Nt, ReviewState as O, renderReviewContent as On, MAX_REVIEW_UNITS as Ot, StoredReviewFinding as P, planReviewUnits as Pt, FanOutCoordinatorToolkitLayer as Q, ReviewConcern as Qt, fromStoredFinding as R, CodeReview as Rt, GitCommitSha as S, MAX_REVIEW_CONTENT_CHARS as Sn, fileReviewerInstructions as St, ReviewHeadComparison as T, hasReviewableContent as Tn, makeFileReviewerInstructions as Tt, unavailableReviewStateAuthenticatorLayer as U, FindingSeverity as Ut, toStoredConcern as V, FileSlice as Vt, validateReviewState as W, ListChangedFiles as Wt, DelegateFileReview as X, ReadFile as Xt, renderFingerprintMarker as Y, REVIEW_TOOL_RESULT_MAX_BYTES as Yt, FanOutCoordinatorToolkit as Z, ReadFileDiff as Zt, ReviewRetirementHost as _, ReviewInputViolation as _n, fanOutHandlersLayer as _t, PriorReviews as a, defaultReviewPolicy as an, FileReviewToolkit as at, hasReviewMetadataMarker as b, ChangedFileStatus as bn, fileReviewDelegation as bt, fingerprintUnchanged as c, readFileDiffHandler as cn, FileReviewUnitResult as ct, gitHubReviewPublisherLayer as d, reviewInstructions as dn, ListReviewUnitsQuery as dt, ReviewMission as en, FanOutReviewer as et, gitHubReviewRetirementHostLayer as f, MAX_CHANGED_FILES as fn, MAX_CHILD_CONCERNS as ft, ReviewRetirementFailure as g, PullRequestSourceFailure as gn, defaultFileReviewerPolicy as gt, RetirableReviewComment as h, PullRequestSource as hn, defaultFanOutPolicy as ht, PriorReviewLookupFailure as i, clampMaxFindings as in, FileReviewRequest as it, ReviewStateMarker as j, ReviewUnitId as jt, ReviewStateAuthenticationFailure as k, MAX_UNIT_FILES as kt, gitHubPriorReviewsLayer as l, readFileHandler as ln, FileReviewer as lt, RetirableReview as m, PullRequestMetadata as mn, MAX_FILE_REVIEW_TOOL_CALLS as mt, GitHubApiFailure as n, ReviewToolkitLayer as nn, FileReviewDelegationFailure as nt, PublishedReview as o, listChangedFilesHandler as on, FileReviewToolkitLayer as ot, parseGitHubSubmittedAt as p, MAX_FILE_CHARS as pn, MAX_CHILD_FINDINGS as pt, computeChangesetFingerprint as q, MAX_FINDINGS as qt, GitHubReviewTarget as r, ReviewVerdict as rn, FileReviewReport as rt, ReviewPublisher as s, makeReviewInstructions as sn, FileReviewUnitFailed as st, DEFAULT_GITHUB_REVIEW_AUTHOR_LOGIN as t, ReviewToolkit as tn, FileReviewBrief as tt, gitHubPullRequestSourceLayer as u, resolveGuidance as un, ListReviewUnits as ut, ReviewRetirementReport as v, normalizeRepoRelativePath as vn, fanOutHandlersLayerFor as vt, ReviewExecutionContext as w, commentableLines as wn, makeFanOutReviewSuite as wt, retireStaleReviews as x, ChangedPath as xn, fileReviewPolicy as xt, decideReviewRetirement as y, ChangedFile as yn, fanOutReviewInstructions as yt, selectReviewRange as z, FileDiffQuery as zt };
1675
1797
 
1676
- //# sourceMappingURL=github-5TCFrxfX.mjs.map
1798
+ //# sourceMappingURL=github-CnGU7FFJ.mjs.map