@effect-agent/pr-review 0.1.0-beta.36 → 0.1.0-beta.38

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/NOTICE ADDED
@@ -0,0 +1,27 @@
1
+ This package includes adaptations of the review instructions and numbered diff
2
+ hunk presentation from PR-Agent:
3
+
4
+ https://github.com/The-PR-Agent/pr-agent
5
+ Pinned source: 9e6d6a5b40f9ce90bcc085466ba7a42c0837c37a
6
+
7
+ MIT License
8
+
9
+ Copyright (c) 2026 The PR Agent
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
package/README.md CHANGED
@@ -1,17 +1,40 @@
1
1
  # @effect-agent/pr-review
2
2
 
3
- A small, provider-neutral review agent.
3
+ A small, provider-neutral review agent. One bounded model run receives every admitted patch as
4
+ numbered new and old hunks, reads immutable base or head source when needed, and returns findings
5
+ through a required native completion Tool. There is no voting, candidate cache, private hypothesis
6
+ handoff, or repository code execution.
4
7
 
5
- The package accepts an already-collected diff, makes one model call with no
6
- tools, validates the returned paths and line anchors, and returns a structured
7
- report with cached, uncached, cache-write, and output token usage plus, when
8
- supplied by the host, an estimated cost. It knows nothing about GitHub,
9
- webhooks, comments, providers, retries, or review history; those belong to the
10
- host channel.
11
- Each finding carries a severity and problem category so a host can render a
12
- scannable review without another model call.
8
+ The reviewer traces changed entry points and boundaries through downstream consumers, guards,
9
+ finite resources, transformations, effects, completion, and unchanged callees. A finding must have
10
+ a supported trigger, concrete terminal failure, causative changed edge, reachable impact, and a
11
+ cause-level repair checked against both a legitimate boundary input and excluded scope. Incremental
12
+ findings must be introduced, exposed, or materially affected by the exact delta; unrelated old bugs
13
+ and target-only changes remain out of scope, while explicit reverts remain reviewable.
14
+
15
+ The result contains model findings with host-validated paths and line anchors, exact duplicate
16
+ removal, aggregate usage, and optional host-priced cost. Unknown changed paths fail closed and
17
+ invalid inline anchors become top-level findings. Model output, usage, context, and retained response
18
+ bytes remain bounded. Public finding paths, titles, and bodies retain their 512, 200, and
19
+ 2,000-character limits.
20
+
21
+ The reviewer does not resolve previous findings or declare a partial review safe
22
+ to merge. GitHub history, credentials, diff collection, and publication belong to
23
+ the host channel.
13
24
 
14
25
  ```ts
15
26
  const reviewer = makeReviewer({ model, guidance, estimateCostMicrousd });
16
- const outcome = yield * reviewer.review(request);
27
+ const program = reviewer.review(request).pipe(Effect.provideService(ReviewRepository, repository));
17
28
  ```
29
+
30
+ `repository.readFile` and `repository.findFiles` return typed Effects. Hosts must
31
+ authorize the source sent to their model, enforce immutable revisions and read
32
+ bounds, and treat source content as untrusted data. The reviewer exposes this
33
+ dependency in its Effect requirements; it has no ambient filesystem or network
34
+ access and does not cache review answers.
35
+
36
+ `ReviewSource.fromText(request, text)` applies the shared line and character
37
+ bounds after the host authorizes and reads a file.
38
+
39
+ The numbered hunk presentation and portions of the review instructions are adapted from
40
+ [PR-Agent](https://github.com/The-PR-Agent/pr-agent). See `NOTICE` for its MIT license attribution.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,49 @@
1
- import { Effect, Schema } from "effect";
2
- import { AgentPolicy, IdGenerator, RunCostEstimator, UsageBudgetLimits } from "effect-agent";
3
- import { LanguageModel, Model, Toolkit } from "effect/unstable/ai";
1
+ import { Context, Effect, Schema } from "effect";
2
+ import { IdGenerator, RunCostEstimator } from "effect-agent";
3
+ import { LanguageModel, Model, Tool, Toolkit } from "effect/unstable/ai";
4
+ //#region src/repository.d.ts
5
+ declare const ReadFileInput: Schema.Struct<{
6
+ readonly path: Schema.NonEmptyString;
7
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
8
+ readonly startLine: Schema.Int;
9
+ readonly lineCount: Schema.Int;
10
+ }>;
11
+ declare const ReviewContextError_base: Schema.Class<ReviewContextError, Schema.TaggedStruct<"ReviewContextError", {
12
+ readonly message: Schema.NonEmptyString;
13
+ }>, import("effect/Cause").YieldableError>;
14
+ declare class ReviewContextError extends ReviewContextError_base {}
15
+ declare const ReviewSource_base: Schema.Class<ReviewSource, Schema.Struct<{
16
+ readonly path: Schema.NonEmptyString;
17
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
18
+ readonly startLine: Schema.Int;
19
+ readonly totalLines: Schema.Natural;
20
+ readonly content: Schema.String;
21
+ }>, {}>;
22
+ declare class ReviewSource extends ReviewSource_base {
23
+ /** Apply the same line and character bounds in live and frozen-source adapters. */
24
+ static readonly fromText: (input: {
25
+ readonly path: string;
26
+ readonly revision: "base" | "head";
27
+ readonly startLine: number;
28
+ readonly lineCount: number;
29
+ }, text: string) => Effect.Effect<ReviewSource, ReviewContextError, never>;
30
+ }
31
+ declare const ReviewFileList_base: Schema.Class<ReviewFileList, Schema.Struct<{
32
+ readonly paths: Schema.$Array<Schema.NonEmptyString>;
33
+ readonly truncated: Schema.Boolean;
34
+ }>, {}>;
35
+ declare class ReviewFileList extends ReviewFileList_base {}
36
+ declare const FindFilesInput: Schema.Struct<{
37
+ readonly query: Schema.String;
38
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
39
+ }>;
40
+ declare const ReviewRepository_base: Context.ServiceClass<ReviewRepository, "@effect-agent/pr-review/ReviewRepository", {
41
+ readonly readFile: (input: typeof ReadFileInput.Type) => Effect.Effect<ReviewSource, ReviewContextError>;
42
+ readonly findFiles: (input: typeof FindFilesInput.Type) => Effect.Effect<ReviewFileList, ReviewContextError>;
43
+ }>;
44
+ /** Read-only source access bound by the host to the request's exact two revisions. */
45
+ declare class ReviewRepository extends ReviewRepository_base {}
46
+ //#endregion
4
47
  //#region src/review.d.ts
5
48
  declare const ReviewChange_base: Schema.Class<ReviewChange, Schema.Struct<{
6
49
  readonly path: Schema.NonEmptyString;
@@ -13,6 +56,7 @@ declare const ReviewRequest_base: Schema.Class<ReviewRequest, Schema.Struct<{
13
56
  readonly description: Schema.String;
14
57
  readonly baseRevision: Schema.NonEmptyString;
15
58
  readonly headRevision: Schema.NonEmptyString;
59
+ readonly scope: Schema.optionalKey<Schema.Literals<readonly ["full", "incremental"]>>;
16
60
  readonly changes: Schema.$Array<typeof ReviewChange>;
17
61
  readonly unreviewedPaths: Schema.$Array<Schema.NonEmptyString>;
18
62
  }>, {}>;
@@ -21,14 +65,14 @@ declare class ReviewRequest extends ReviewRequest_base {}
21
65
  declare const ReviewSeverity: Schema.Literals<readonly ["blocking", "important", "nit"]>;
22
66
  type ReviewSeverity = typeof ReviewSeverity.Type;
23
67
  /** A model-claimed problem kind used only to label findings for readers. */
24
- declare const ReviewCategory: Schema.Literals<readonly ["correctness", "security", "concurrency", "performance", "resources", "reliability", "error-handling", "testing", "maintainability", "style", "docs"]>;
68
+ declare const ReviewCategory: Schema.Literals<readonly ["correctness", "security", "concurrency", "performance", "resources", "reliability", "error-handling", "testing", "maintainability", "docs"]>;
25
69
  type ReviewCategory = typeof ReviewCategory.Type;
26
70
  declare const ReviewFinding_base: Schema.Class<ReviewFinding, Schema.Struct<{
27
71
  readonly path: Schema.NonEmptyString;
28
72
  readonly line: Schema.optionalKey<Schema.Int>;
29
73
  readonly severity: Schema.Literals<readonly ["blocking", "important", "nit"]>;
30
74
  /** Presentation label only; it never changes review admission or failure policy. */
31
- readonly category: Schema.Literals<readonly ["correctness", "security", "concurrency", "performance", "resources", "reliability", "error-handling", "testing", "maintainability", "style", "docs"]>;
75
+ readonly category: Schema.Literals<readonly ["correctness", "security", "concurrency", "performance", "resources", "reliability", "error-handling", "testing", "maintainability", "docs"]>;
32
76
  readonly title: Schema.NonEmptyString;
33
77
  readonly body: Schema.NonEmptyString;
34
78
  }>, {}>;
@@ -38,7 +82,7 @@ declare const ReviewReport_base: Schema.Class<ReviewReport, Schema.Struct<{
38
82
  readonly summary: Schema.NonEmptyString;
39
83
  readonly findings: Schema.$Array<typeof ReviewFinding>;
40
84
  }>, {}>;
41
- /** The only model-authored output. An empty findings array is a successful review. */
85
+ /** Host-validated findings with a host-authored summary of the reviewed scope. */
42
86
  declare class ReviewReport extends ReviewReport_base {}
43
87
  declare const ReviewUsage_base: Schema.Class<ReviewUsage, Schema.Struct<{
44
88
  readonly inputTokens: Schema.Natural;
@@ -55,48 +99,92 @@ declare const ReviewOutcome_base: Schema.Class<ReviewOutcome, Schema.Struct<{
55
99
  readonly usage: typeof ReviewUsage;
56
100
  }>, {}>;
57
101
  declare class ReviewOutcome extends ReviewOutcome_base {}
58
- declare const reviewPolicy: AgentPolicy;
59
- declare const reviewBudgetLimits: UsageBudgetLimits;
60
- /** Return every RIGHT-side line on which GitHub can place a diff comment. */
61
- declare const commentableLines: (patch: string) => ReadonlySet<number>;
102
+ declare const ReviewSubmission_base: Schema.Class<ReviewSubmission, Schema.Struct<{
103
+ readonly findings: Schema.$Array<Schema.Struct<{
104
+ readonly path: Schema.NonEmptyString;
105
+ readonly line: Schema.optionalKey<Schema.Int>;
106
+ readonly category: Schema.Literals<readonly ["correctness", "security", "concurrency", "performance", "resources", "reliability", "error-handling", "testing", "maintainability", "docs"]>;
107
+ readonly title: Schema.NonEmptyString;
108
+ readonly body: Schema.NonEmptyString;
109
+ readonly priority: Schema.Literals<readonly [0, 1, 2, 3]>;
110
+ }>>;
111
+ }>, {}>;
112
+ declare class ReviewSubmission extends ReviewSubmission_base {}
113
+ declare const FormattedReviewRequest_base: Schema.Class<FormattedReviewRequest, Schema.Struct<{
114
+ readonly title: Schema.String;
115
+ readonly description: Schema.String;
116
+ readonly baseRevision: Schema.NonEmptyString;
117
+ readonly headRevision: Schema.NonEmptyString;
118
+ readonly scope: Schema.optionalKey<Schema.Literals<readonly ["full", "incremental"]>>;
119
+ readonly unreviewedPaths: Schema.$Array<Schema.NonEmptyString>;
120
+ readonly changes: Schema.$Array<Schema.Struct<{
121
+ readonly path: Schema.NonEmptyString;
122
+ readonly formattedDiff: Schema.NonEmptyString;
123
+ }>>;
124
+ }>, {}>;
125
+ declare class FormattedReviewRequest extends FormattedReviewRequest_base {}
126
+ declare const ReviewVerificationError_base: Schema.Class<ReviewVerificationError, Schema.TaggedStruct<"ReviewVerificationError", {
127
+ readonly message: Schema.String;
128
+ }>, import("effect/Cause").YieldableError>;
129
+ declare class ReviewVerificationError extends ReviewVerificationError_base {}
62
130
  declare const isCommentableLine: (patch: string, line: number) => boolean;
63
- /**
64
- * Treat model output as untrusted: remove unknown paths, demote invalid line
65
- * anchors to top-level findings, and collapse exact duplicates.
66
- */
67
- declare const sanitizeReviewReport: (request: Pick<ReviewRequest, "changes">, report: ReviewReport) => ReviewReport;
68
131
  interface ReviewerOptions<Provider, ModelProvides, ModelRequires> {
69
132
  readonly model: Model.Model<Provider, LanguageModel.LanguageModel | ModelProvides, ModelRequires>;
70
133
  readonly guidance?: string | undefined;
71
134
  readonly estimateCostMicrousd?: RunCostEstimator | undefined;
72
135
  }
73
- /** Build a provider-neutral reviewer. The returned `review` performs exactly one Run. */
136
+ /** One bounded, source-backed review of the complete admitted delta. */
74
137
  declare const makeReviewer: <Provider, ModelProvides, ModelRequires>(options: ReviewerOptions<Provider, ModelProvides, ModelRequires>) => {
75
- readonly definition: import("effect-agent").Definition<typeof ReviewRequest, typeof ReviewReport, "Review the supplied pull-request diff once.\n\nReport only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.\n\nEvery finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches." | `Review the supplied pull-request diff once.
76
-
77
- Report only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.
78
-
79
- Every finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches.
80
-
81
- Repository guidance:
82
- ${string}`, Toolkit.Toolkit<{}>, undefined>;
83
- readonly binding: import("effect-agent").Binding<import("effect-agent").Definition<typeof ReviewRequest, typeof ReviewReport, "Review the supplied pull-request diff once.\n\nReport only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.\n\nEvery finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches." | `Review the supplied pull-request diff once.
84
-
85
- Report only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.
86
-
87
- Every finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches.
88
-
89
- Repository guidance:
90
- ${string}`, Toolkit.Toolkit<{}>, undefined>, Model.Model<Provider, ModelProvides | LanguageModel.LanguageModel, ModelRequires>>;
91
- readonly review: (request: ReviewRequest) => Effect.Effect<ReviewOutcome, import("effect-agent").AgentRuntimeFailure<import("effect-agent").RuntimeBinding<typeof ReviewRequest, typeof ReviewReport, "Review the supplied pull-request diff once.\n\nReport only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.\n\nEvery finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches." | `Review the supplied pull-request diff once.
92
-
93
- Report only concrete correctness, security, reliability, or maintainability defects that the author should act on. Do not praise, restate the change, invent missing repository context, or ask for speculative cleanup. An empty findings array is valid.
94
-
95
- Every finding must use an exact supplied path. Set line only to a RIGHT-side added or context line visible in that path's unified patch; otherwise omit line. Use blocking only for a defect that should prevent shipping. Classify each finding with the closest available category. Treat unreviewedPaths as unavailable scope and never imply that you inspected it. A changed file absent from changes may have been withheld by the host; never infer that it was not changed, and report only defects proven by the supplied patches.
96
-
97
- Repository guidance:
98
- ${string}`, {}, Provider, ModelProvides, ModelRequires, never, never, undefined>, import("effect-agent").BudgetAdapterError | import("effect-agent").BudgetExceeded, never>, Exclude<Exclude<Exclude<ModelRequires, import("effect-agent").EngineProvidedToolServices>, IdGenerator>, import("effect/Scope").Scope>>;
138
+ readonly review: (request: ReviewRequest) => Effect.Effect<ReviewOutcome, ReviewVerificationError | import("effect-agent").AgentRuntimeFailure<import("effect-agent").RuntimeBinding<typeof FormattedReviewRequest, typeof ReviewSubmission, string, {
139
+ readonly find_files: Tool.Tool<"find_files", {
140
+ readonly parameters: Schema.Struct<{
141
+ readonly query: Schema.String;
142
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
143
+ }>;
144
+ readonly success: typeof ReviewFileList;
145
+ readonly failure: typeof ReviewContextError;
146
+ readonly failureMode: "return";
147
+ }, never>;
148
+ readonly read_file: Tool.Tool<"read_file", {
149
+ readonly parameters: Schema.Struct<{
150
+ readonly path: Schema.NonEmptyString;
151
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
152
+ readonly startLine: Schema.Int;
153
+ readonly lineCount: Schema.Int;
154
+ }>;
155
+ readonly success: typeof ReviewSource;
156
+ readonly failure: typeof ReviewContextError;
157
+ readonly failureMode: "return";
158
+ }, never>;
159
+ readonly submit_review: Tool.Tool<"submit_review", {
160
+ readonly parameters: typeof ReviewSubmission;
161
+ readonly success: Schema.Null;
162
+ readonly failure: Schema.Never;
163
+ readonly failureMode: "error";
164
+ }, never>;
165
+ }, Provider, ModelProvides, ModelRequires, never, never, undefined>, import("effect-agent").BudgetAdapterError | import("effect-agent").BudgetExceeded, never>, ReviewRepository | Exclude<Exclude<Exclude<ModelRequires, import("effect-agent").EngineProvidedToolServices>, Tool.Handler<"submit_review"> | IdGenerator | Tool.HandlersFor<{
166
+ readonly find_files: Tool.Tool<"find_files", {
167
+ readonly parameters: Schema.Struct<{
168
+ readonly query: Schema.String;
169
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
170
+ }>;
171
+ readonly success: typeof ReviewFileList;
172
+ readonly failure: typeof ReviewContextError;
173
+ readonly failureMode: "return";
174
+ }, never>;
175
+ readonly read_file: Tool.Tool<"read_file", {
176
+ readonly parameters: Schema.Struct<{
177
+ readonly path: Schema.NonEmptyString;
178
+ readonly revision: Schema.Literals<readonly ["base", "head"]>;
179
+ readonly startLine: Schema.Int;
180
+ readonly lineCount: Schema.Int;
181
+ }>;
182
+ readonly success: typeof ReviewSource;
183
+ readonly failure: typeof ReviewContextError;
184
+ readonly failureMode: "return";
185
+ }, never>;
186
+ }>>, import("effect/Scope").Scope>>;
99
187
  };
100
188
  //#endregion
101
- export { ReviewCategory, ReviewChange, ReviewFinding, ReviewOutcome, ReviewReport, ReviewRequest, ReviewSeverity, ReviewUsage, ReviewerOptions, type RunCostEstimator, commentableLines, isCommentableLine, makeReviewer, reviewBudgetLimits, reviewPolicy, sanitizeReviewReport };
189
+ export { ReviewCategory, ReviewChange, ReviewContextError, ReviewFileList, ReviewFinding, ReviewOutcome, ReviewReport, ReviewRepository, ReviewRequest, ReviewSeverity, ReviewSource, ReviewUsage, ReviewVerificationError, ReviewerOptions, type RunCostEstimator, isCommentableLine, makeReviewer };
102
190
  //# sourceMappingURL=index.d.mts.map