@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 +1 -2
- package/README.md +73 -11
- package/dist/index.d.mts +34 -55
- package/dist/index.mjs +188 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
- package/src/repository.ts +2 -2
- package/src/review.ts +279 -118
package/NOTICE
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
This package includes adaptations of the review instructions
|
|
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.
|
|
4
|
-
|
|
5
|
-
through a required native completion Tool.
|
|
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
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
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").
|
|
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
|