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

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 CHANGED
@@ -1,5 +1,4 @@
1
- This package includes adaptations of the review instructions and numbered diff
2
- hunk presentation from PR-Agent:
1
+ This package includes adaptations of the review instructions from PR-Agent:
3
2
 
4
3
  https://github.com/The-PR-Agent/pr-agent
5
4
  Pinned source: 9e6d6a5b40f9ce90bcc085466ba7a42c0837c37a
package/README.md CHANGED
@@ -1,16 +1,33 @@
1
1
  # @effect-agent/pr-review
2
2
 
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
3
+ A small, provider-neutral review agent. Bounded model runs receive admitted patches as
4
+ literal unified diffs, read immutable base or head source when needed, record established
5
+ findings with `record_finding`, and return findings through a required native completion Tool.
6
+ There is no voting, candidate cache, private hypothesis
6
7
  handoff, or repository code execution.
7
8
 
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.
9
+ The native Agent `inputPrompt` projects each complete patch once, with literal newlines. It keeps
10
+ file headers, hunk ranges, additions, deletions, context, and mode or rename metadata. It does not
11
+ duplicate context into separate old/new views or JSON-escape the source for the model. The canonical
12
+ `ReviewRequest` and finding validation retain the original patches. This reduces repeated input
13
+ overhead without excluding changes; it does not guarantee a complete review within a spending cap.
14
+
15
+ The reviewer assesses every supplied patch first. Source reads resolve concrete questions about
16
+ plausible defects, such as a missing caller, guard, contract, or limit. It reuses supplied evidence
17
+ and finishes when those questions are resolved; straightforward changes can finish without source
18
+ tools. Reads prioritize implementation and owned boundary schemas over test examples, including
19
+ the definitions needed to resolve the question rather than only a nearby call site.
20
+ Findings explain a supported trigger, concrete impact, and needed correction. Changes that
21
+ expose an unchanged downstream failure remain eligible. Incremental findings must arise from the
22
+ exact delta; unrelated old bugs and target-only changes stay out of scope, while explicit reverts
23
+ remain reviewable.
24
+ Changes to collection membership, cardinality, or representation warrant checking affected
25
+ consumer limits with a supported boundary input, including transformations and aggregation.
26
+ New or moved resource acquisition warrants checking an early-failure sequence and its cleanup.
27
+ Owned untrusted-input and model-output Schema boundaries must safely handle every admitted value,
28
+ including adversarial values at the field and collection bounds.
29
+ Novelty compares base and head with the same supported operation input, including when a
30
+ previously failing helper becomes newly reachable.
14
31
 
15
32
  The result contains model findings with host-validated paths and line anchors, exact duplicate
16
33
  removal, aggregate usage, and optional host-priced cost. Unknown changed paths fail closed and
@@ -22,8 +39,53 @@ The reviewer does not resolve previous findings or declare a partial review safe
22
39
  to merge. GitHub history, credentials, diff collection, and publication belong to
23
40
  the host channel.
24
41
 
42
+ Without host spending admission, the engine owns a cumulative 416,000-token stop policy and
43
+ reserves 160,000 tokens for a final context and completion response. The model sees its current
44
+ turn, tool, and token usage. Token, turn, or tool exhaustion permits one constrained completion
45
+ through `submit_review`; it returns validated findings and accounted usage with
46
+ `ReviewOutcome.exhausted` naming the limit. Hosts must
47
+ treat that outcome as incomplete, even when it contains no findings. Measured usage can exceed a
48
+ policy threshold before the engine observes it; this is not a provider-side spending cap.
49
+ The usage ledger records research, compaction, and finalization without a second token limit that
50
+ could abort delivery.
51
+
52
+ An optional `costControl` reports the host's pre-request spending admission and provider usage.
53
+ Supplying it replaces the cumulative token quota and completion reserve with that admission.
54
+ Cached reads still contribute to usage diagnostics, but cannot force early token finalization.
55
+ The 8-turn, 64-tool-call, 5-minute, and 128,000-token context bounds remain in force. A cost
56
+ estimator alone does not disable the token quota. Capped hosts own model-visible spending feedback
57
+ at their provider boundary; the generic turn/tool status is disabled for these runs. The Action
58
+ counts its outgoing spending status before admission and keeps it outside the reusable cache prefix.
59
+ With `costControl`, large requests run in sequential batches of at most 256,000 patch characters,
60
+ preserving the host's file order and keeping each patch complete. Each batch has a fresh context
61
+ and the same source service. All batches share the host ledger, turn and tool allowances, deadline,
62
+ and 24-finding capacity. They stop on an incomplete result or exhaustion. `pendingPaths` identifies
63
+ admitted patches never sent to a model, including a batch refused before paid inference. Hosts
64
+ must disclose those paths as unreviewed. Without `costControl`, the reviewer retains one run and its
65
+ cumulative token policy.
66
+ When the host stops research for cost, the reviewer returns `exhausted: "cost"` and delivers
67
+ recorded findings without requiring another paid call. Hosts must reserve the full possible charge
68
+ before sending each request; the port itself does not enforce a cap. The
69
+ [GitHub Action](../../action/README.md) supplies that implementation for its supported OpenAI models.
70
+ `reservedCostMicrousd` reports the maximum additional charge for requests whose usage is still
71
+ unknown, separately from the observed usage estimate.
72
+
73
+ Recorded findings also survive a later expected execution or verification failure. Such a result
74
+ has `incomplete: true`; hosts must not treat an empty or partial result as clearing the change.
75
+ The model can also set `incomplete: true` in `submit_review` when it cannot finish assessing the
76
+ supplied patches. That declaration preserves findings and becomes `ReviewOutcome.incomplete`
77
+ even when no engine limit or provider failure occurred. Host-tracked `unreviewedPaths` remain
78
+ disclosed separately and do not by themselves mark the admitted patches unfinished. An empty
79
+ complete result is not proof that the repository is defect-free.
80
+ With `costControl`, an accounted provider attempt also returns an incomplete outcome after an
81
+ expected failure, even without findings, so hosts can publish its usage and outstanding charges.
82
+ Otherwise failures without recorded findings remain typed. Defects and interruption still
83
+ propagate, and these records belong to the current run's Scope, not persistent storage.
84
+ The report retains recorded findings before adding newly submitted findings, removes exact
85
+ duplicates, and marks coverage incomplete if the combined report exceeds 24 findings.
86
+
25
87
  ```ts
26
- const reviewer = makeReviewer({ model, guidance, estimateCostMicrousd });
88
+ const reviewer = makeReviewer({ model, guidance, estimateCostMicrousd, costControl });
27
89
  const program = reviewer.review(request).pipe(Effect.provideService(ReviewRepository, repository));
28
90
  ```
29
91
 
@@ -36,5 +98,5 @@ access and does not cache review answers.
36
98
  `ReviewSource.fromText(request, text)` applies the shared line and character
37
99
  bounds after the host authorizes and reads a file.
38
100
 
39
- The numbered hunk presentation and portions of the review instructions are adapted from
101
+ Portions of the review instructions are adapted from
40
102
  [PR-Agent](https://github.com/The-PR-Agent/pr-agent). See `NOTICE` for its MIT license attribution.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect, Schema } from "effect";
2
- import { IdGenerator, RunCostEstimator } from "effect-agent";
2
+ import { IdGenerator, RunCostEstimator, ThreadHistory } from "effect-agent";
3
3
  import { LanguageModel, Model, Tool, Toolkit } from "effect/unstable/ai";
4
4
  //#region src/repository.d.ts
5
5
  declare const ReadFileInput: Schema.Struct<{
@@ -91,38 +91,43 @@ declare const ReviewUsage_base: Schema.Class<ReviewUsage, Schema.Struct<{
91
91
  readonly cacheWriteInputTokens: Schema.Natural;
92
92
  readonly outputTokens: Schema.Natural;
93
93
  readonly estimatedCostMicrousd: Schema.optionalKey<Schema.Natural>;
94
+ /** Maximum additional charge for sent requests whose usage remains unknown. */
95
+ readonly reservedCostMicrousd: Schema.optionalKey<Schema.Natural>;
94
96
  }>, {}>;
95
97
  declare class ReviewUsage extends ReviewUsage_base {}
98
+ declare const ReviewCostSnapshot_base: Schema.Class<ReviewCostSnapshot, Schema.Struct<{
99
+ readonly stopped: Schema.Boolean;
100
+ /** Admitted provider attempts, including failed or still-unmetered requests. */
101
+ readonly modelCalls: Schema.Natural;
102
+ readonly usage: typeof ReviewUsage;
103
+ }>, {}>;
104
+ /** Host accounting covers every provider attempt, including compaction and failed requests. */
105
+ declare class ReviewCostSnapshot extends ReviewCostSnapshot_base {}
106
+ /**
107
+ * A host must reserve the full possible charge before provider I/O. If admission
108
+ * stops, the reviewer delivers recorded findings without another model request.
109
+ * This port reports that decision; it does not enforce a spending limit itself.
110
+ * Supplying it replaces the cumulative token quota with the host's admission;
111
+ * per-context, turn, tool, and duration limits still apply. Accounted attempts
112
+ * return incomplete outcomes on expected failure, even without findings.
113
+ * Capped hosts own model-visible spending feedback at their provider boundary;
114
+ * the reviewer's generic turn/tool status is disabled for these runs.
115
+ */
116
+ interface ReviewCostControl {
117
+ readonly snapshot: Effect.Effect<ReviewCostSnapshot>;
118
+ }
96
119
  declare const ReviewOutcome_base: Schema.Class<ReviewOutcome, Schema.Struct<{
97
120
  readonly report: typeof ReviewReport;
98
121
  readonly turns: Schema.Natural;
99
122
  readonly usage: typeof ReviewUsage;
123
+ /** Admitted patches in batches that never started. These are not reviewed files. */
124
+ readonly pendingPaths: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
125
+ /** A constrained final answer preserves findings but cannot establish complete coverage. */
126
+ readonly exhausted: Schema.optionalKey<Schema.Literals<readonly ["tokens", "tool-calls", "turns", "cost"]>>;
127
+ /** Unfinished coverage, reported by the model or caused by failure or the report capacity bound. */
128
+ readonly incomplete: Schema.optionalKey<Schema.Literal<true>>;
100
129
  }>, {}>;
101
130
  declare class ReviewOutcome extends ReviewOutcome_base {}
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
131
  declare const ReviewVerificationError_base: Schema.Class<ReviewVerificationError, Schema.TaggedStruct<"ReviewVerificationError", {
127
132
  readonly message: Schema.String;
128
133
  }>, import("effect/Cause").YieldableError>;
@@ -132,37 +137,11 @@ interface ReviewerOptions<Provider, ModelProvides, ModelRequires> {
132
137
  readonly model: Model.Model<Provider, LanguageModel.LanguageModel | ModelProvides, ModelRequires>;
133
138
  readonly guidance?: string | undefined;
134
139
  readonly estimateCostMicrousd?: RunCostEstimator | undefined;
140
+ readonly costControl?: ReviewCostControl | undefined;
135
141
  }
136
- /** One bounded, source-backed review of the complete admitted delta. */
142
+ /** A bounded review, with sequential patch batches when a shared spending ledger is supplied. */
137
143
  declare const makeReviewer: <Provider, ModelProvides, ModelRequires>(options: ReviewerOptions<Provider, ModelProvides, ModelRequires>) => {
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<{
144
+ readonly review: (request: ReviewRequest) => Effect.Effect<ReviewOutcome, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect-agent").AgentToolAuthorizationDenied | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | import("effect-agent").BudgetExceeded | import("effect-agent").CompactionError | import("effect-agent").ContextBudgetError | import("effect-agent").ContextOverflowError | import("effect-agent").ModelProtocolError | ReviewVerificationError | import("effect-agent").ThreadHistoryError, ReviewRepository | Exclude<Exclude<Exclude<Exclude<(import("effect-agent").ModelServices extends ModelProvides | LanguageModel.LanguageModel | Model.ModelName | Model.ProviderName ? Model.Model<Provider, ModelProvides | LanguageModel.LanguageModel, ModelRequires> : never) extends (infer T) ? T extends (import("effect-agent").ModelServices extends ModelProvides | LanguageModel.LanguageModel | Model.ModelName | Model.ProviderName ? Model.Model<Provider, ModelProvides | LanguageModel.LanguageModel, ModelRequires> : never) ? T extends import("effect/Layer").Layer<infer _Provides, infer _Error, infer Services> ? Services : never : never : never, import("effect-agent").EngineProvidedToolServices>, Tool.Handler<"record_finding">>, Tool.Handler<"submit_review"> | IdGenerator | ThreadHistory | Tool.HandlersFor<{
166
145
  readonly find_files: Tool.Tool<"find_files", {
167
146
  readonly parameters: Schema.Struct<{
168
147
  readonly query: Schema.String;
@@ -186,5 +165,5 @@ declare const makeReviewer: <Provider, ModelProvides, ModelRequires>(options: Re
186
165
  }>>, import("effect/Scope").Scope>>;
187
166
  };
188
167
  //#endregion
189
- export { ReviewCategory, ReviewChange, ReviewContextError, ReviewFileList, ReviewFinding, ReviewOutcome, ReviewReport, ReviewRepository, ReviewRequest, ReviewSeverity, ReviewSource, ReviewUsage, ReviewVerificationError, ReviewerOptions, type RunCostEstimator, isCommentableLine, makeReviewer };
168
+ export { ReviewCategory, ReviewChange, ReviewContextError, ReviewCostControl, ReviewCostSnapshot, ReviewFileList, ReviewFinding, ReviewOutcome, ReviewReport, ReviewRepository, ReviewRequest, ReviewSeverity, ReviewSource, ReviewUsage, ReviewVerificationError, ReviewerOptions, type RunCostEstimator, isCommentableLine, makeReviewer };
190
169
  //# sourceMappingURL=index.d.mts.map