@oss-autopilot/core 3.0.1 → 3.1.0
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/dist/cli.bundle.cjs +73 -72
- package/dist/commands/scout-bridge.d.ts +12 -1
- package/dist/commands/scout-bridge.js +19 -0
- package/dist/commands/vet-list.js +10 -2
- package/dist/commands/vet.js +10 -1
- package/dist/core/state-schema.d.ts +4 -0
- package/dist/core/state-schema.js +13 -0
- package/dist/formatters/json.d.ts +28 -0
- package/package.json +7 -7
|
@@ -2,7 +2,18 @@
|
|
|
2
2
|
* Bridge between oss-autopilot's AgentState and oss-scout's OssScout API.
|
|
3
3
|
* Maps state fields and creates scout instances for search/vet commands.
|
|
4
4
|
*/
|
|
5
|
-
import { type OssScout, type ScoutState } from '@oss-scout/core';
|
|
5
|
+
import { type LinkedPR as ScoutLinkedPR, type OssScout, type ScoutState } from '@oss-scout/core';
|
|
6
|
+
import type { LinkedPR } from '../core/linked-pr-classification.js';
|
|
7
|
+
/**
|
|
8
|
+
* Convert scout 0.6.0's `LinkedPR` (separate `state` + `merged`) into the
|
|
9
|
+
* shape `classifyLinkedPR` expects (`state` already folded with `merged`).
|
|
10
|
+
*
|
|
11
|
+
* Scout exposes the raw GitHub fields verbatim, but the classifier was
|
|
12
|
+
* written before scout surfaced this data and uses a tri-state
|
|
13
|
+
* `'open' | 'closed' | 'merged'` enum. Folding `merged` into the state
|
|
14
|
+
* preserves the function's existing contract + tests.
|
|
15
|
+
*/
|
|
16
|
+
export declare function adaptScoutLinkedPR(scoutLinkedPR: ScoutLinkedPR | null | undefined): LinkedPR | null;
|
|
6
17
|
/**
|
|
7
18
|
* Build a ScoutState from the current AgentState.
|
|
8
19
|
* Maps oss-autopilot's config and state fields to oss-scout's state format.
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
import { createScout } from '@oss-scout/core';
|
|
6
6
|
import { getStateManager, requireGitHubToken } from '../core/index.js';
|
|
7
7
|
import { loadSkippedIssues } from './skip-file-parser.js';
|
|
8
|
+
/**
|
|
9
|
+
* Convert scout 0.6.0's `LinkedPR` (separate `state` + `merged`) into the
|
|
10
|
+
* shape `classifyLinkedPR` expects (`state` already folded with `merged`).
|
|
11
|
+
*
|
|
12
|
+
* Scout exposes the raw GitHub fields verbatim, but the classifier was
|
|
13
|
+
* written before scout surfaced this data and uses a tri-state
|
|
14
|
+
* `'open' | 'closed' | 'merged'` enum. Folding `merged` into the state
|
|
15
|
+
* preserves the function's existing contract + tests.
|
|
16
|
+
*/
|
|
17
|
+
export function adaptScoutLinkedPR(scoutLinkedPR) {
|
|
18
|
+
if (!scoutLinkedPR)
|
|
19
|
+
return null;
|
|
20
|
+
return {
|
|
21
|
+
author: { login: scoutLinkedPR.author },
|
|
22
|
+
state: scoutLinkedPR.merged ? 'merged' : scoutLinkedPR.state,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
8
25
|
/**
|
|
9
26
|
* Build a ScoutState from the current AgentState.
|
|
10
27
|
* Maps oss-autopilot's config and state fields to oss-scout's state format.
|
|
@@ -31,6 +48,8 @@ export function buildScoutState() {
|
|
|
31
48
|
broadPhaseDelayMs: 90000,
|
|
32
49
|
skipBroadWhenSufficientResults: 15,
|
|
33
50
|
persistence: config.persistence,
|
|
51
|
+
slmTriageModel: config.slmTriageModel,
|
|
52
|
+
slmTriageHost: config.slmTriageHost,
|
|
34
53
|
},
|
|
35
54
|
repoScores: state.repoScores,
|
|
36
55
|
starredRepos: config.starredRepos,
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Re-vets all available issues in a curated issue list file via @oss-scout/core.
|
|
4
4
|
*/
|
|
5
5
|
import * as fs from 'fs';
|
|
6
|
-
import { createAutopilotScout } from './scout-bridge.js';
|
|
6
|
+
import { adaptScoutLinkedPR, createAutopilotScout } from './scout-bridge.js';
|
|
7
7
|
import { runParseList, pruneIssueList } from './parse-list.js';
|
|
8
8
|
import { detectIssueList } from './startup.js';
|
|
9
9
|
import { computeSuccessGrade, gradeFromCandidate } from '../core/issue-grading.js';
|
|
10
|
-
import { getStateManager } from '../core/index.js';
|
|
10
|
+
import { getStateManager, classifyLinkedPR } from '../core/index.js';
|
|
11
11
|
const UNKNOWN_GRADE = computeSuccessGrade({ avgResponseDays: null, mergeRate: null, daysSinceLastCommit: null });
|
|
12
12
|
const KNOWN_SKIP_REASONS = new Set([
|
|
13
13
|
'issue_closed',
|
|
@@ -117,6 +117,11 @@ export async function runVetList(options = {}) {
|
|
|
117
117
|
projectHealth: candidate.projectHealth,
|
|
118
118
|
getRepoScore: (repo) => getStateManager().getRepoScore(repo),
|
|
119
119
|
});
|
|
120
|
+
const userLogin = getStateManager().getState().config.githubUsername;
|
|
121
|
+
const linkedPRClassification = classifyLinkedPR({
|
|
122
|
+
linkedPR: adaptScoutLinkedPR(candidate.vettingResult.linkedPR),
|
|
123
|
+
userLogin,
|
|
124
|
+
});
|
|
120
125
|
const vetResult = {
|
|
121
126
|
issue: {
|
|
122
127
|
repo: candidate.issue.repo,
|
|
@@ -130,6 +135,9 @@ export async function runVetList(options = {}) {
|
|
|
130
135
|
reasonsToSkip: candidate.reasonsToSkip,
|
|
131
136
|
projectHealth: candidate.projectHealth,
|
|
132
137
|
vettingResult: candidate.vettingResult,
|
|
138
|
+
antiLLMPolicy: candidate.antiLLMPolicy,
|
|
139
|
+
linkedPRClassification,
|
|
140
|
+
slmTriage: candidate.slmTriage ?? null,
|
|
133
141
|
grade,
|
|
134
142
|
};
|
|
135
143
|
results.push({
|
package/dist/commands/vet.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import { createAutopilotScout } from './scout-bridge.js';
|
|
6
6
|
import { ISSUE_URL_PATTERN, validateGitHubUrl, validateUrl } from './validation.js';
|
|
7
7
|
import { gradeFromCandidate } from '../core/issue-grading.js';
|
|
8
|
-
import { getStateManager } from '../core/index.js';
|
|
8
|
+
import { getStateManager, classifyLinkedPR } from '../core/index.js';
|
|
9
|
+
import { adaptScoutLinkedPR } from './scout-bridge.js';
|
|
9
10
|
/**
|
|
10
11
|
* Vet a specific GitHub issue for claimability and project health.
|
|
11
12
|
*
|
|
@@ -24,6 +25,11 @@ export async function runVet(options) {
|
|
|
24
25
|
projectHealth: candidate.projectHealth,
|
|
25
26
|
getRepoScore: (repo) => getStateManager().getRepoScore(repo),
|
|
26
27
|
});
|
|
28
|
+
const userLogin = getStateManager().getState().config.githubUsername;
|
|
29
|
+
const linkedPRClassification = classifyLinkedPR({
|
|
30
|
+
linkedPR: adaptScoutLinkedPR(candidate.vettingResult.linkedPR),
|
|
31
|
+
userLogin,
|
|
32
|
+
});
|
|
27
33
|
return {
|
|
28
34
|
issue: {
|
|
29
35
|
repo: candidate.issue.repo,
|
|
@@ -37,6 +43,9 @@ export async function runVet(options) {
|
|
|
37
43
|
reasonsToSkip: candidate.reasonsToSkip,
|
|
38
44
|
projectHealth: candidate.projectHealth,
|
|
39
45
|
vettingResult: candidate.vettingResult,
|
|
46
|
+
antiLLMPolicy: candidate.antiLLMPolicy,
|
|
47
|
+
linkedPRClassification,
|
|
48
|
+
slmTriage: candidate.slmTriage ?? null,
|
|
40
49
|
grade,
|
|
41
50
|
};
|
|
42
51
|
}
|
|
@@ -241,6 +241,8 @@ export declare const AgentConfigSchema: z.ZodObject<{
|
|
|
241
241
|
}>>;
|
|
242
242
|
diffToolCustomCommand: z.ZodOptional<z.ZodString>;
|
|
243
243
|
autoFormatBeforePush: z.ZodDefault<z.ZodBoolean>;
|
|
244
|
+
slmTriageModel: z.ZodDefault<z.ZodString>;
|
|
245
|
+
slmTriageHost: z.ZodDefault<z.ZodString>;
|
|
244
246
|
}, z.core.$strip>;
|
|
245
247
|
export declare const LocalRepoCacheSchema: z.ZodObject<{
|
|
246
248
|
repos: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -399,6 +401,8 @@ export declare const AgentStateSchema: z.ZodObject<{
|
|
|
399
401
|
}>>;
|
|
400
402
|
diffToolCustomCommand: z.ZodOptional<z.ZodString>;
|
|
401
403
|
autoFormatBeforePush: z.ZodDefault<z.ZodBoolean>;
|
|
404
|
+
slmTriageModel: z.ZodDefault<z.ZodString>;
|
|
405
|
+
slmTriageHost: z.ZodDefault<z.ZodString>;
|
|
402
406
|
}, z.core.$strip>>;
|
|
403
407
|
lastRunAt: z.ZodDefault<z.ZodString>;
|
|
404
408
|
lastDigestAt: z.ZodOptional<z.ZodString>;
|
|
@@ -151,6 +151,19 @@ export const AgentConfigSchema = z.object({
|
|
|
151
151
|
* the hook does nothing on every push unless the user explicitly enables it.
|
|
152
152
|
*/
|
|
153
153
|
autoFormatBeforePush: z.boolean().default(false),
|
|
154
|
+
/**
|
|
155
|
+
* Optional Ollama model for SLM pre-triage during issue vetting (#1122).
|
|
156
|
+
* Empty disables the feature. Recommended: `gemma4:e4b` (default for
|
|
157
|
+
* capable hardware), `gemma4:e2b` or `qwen3:1.7b` for low-RAM machines.
|
|
158
|
+
* Threaded through to scout via the bridge in `scout-bridge.ts`.
|
|
159
|
+
*/
|
|
160
|
+
slmTriageModel: z.string().default(''),
|
|
161
|
+
/**
|
|
162
|
+
* Optional Ollama HTTP host override. Defaults to `http://127.0.0.1:11434`
|
|
163
|
+
* when empty. Useful when Ollama runs on a different machine on the
|
|
164
|
+
* local network.
|
|
165
|
+
*/
|
|
166
|
+
slmTriageHost: z.string().default(''),
|
|
154
167
|
});
|
|
155
168
|
// ── 6. Cache schemas ─────────────────────────────────────────────────
|
|
156
169
|
export const LocalRepoCacheSchema = z.object({
|
|
@@ -725,6 +725,34 @@ export interface VetOutput {
|
|
|
725
725
|
reasonsToSkip: string[];
|
|
726
726
|
projectHealth: unknown;
|
|
727
727
|
vettingResult: unknown;
|
|
728
|
+
/**
|
|
729
|
+
* Result of scout's anti-LLM policy scan over CONTRIBUTING.md /
|
|
730
|
+
* CODE_OF_CONDUCT.md / README.md (#979). When `matched` is true the issue
|
|
731
|
+
* should be skipped — the project explicitly disallows AI-generated
|
|
732
|
+
* contributions.
|
|
733
|
+
*/
|
|
734
|
+
antiLLMPolicy?: {
|
|
735
|
+
matched: boolean;
|
|
736
|
+
matchedKeywords: string[];
|
|
737
|
+
sourceFile: string | null;
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* Classification of the issue's first linked PR (#978). `'none'` when
|
|
741
|
+
* no linked PR exists. The other buckets distinguish whether the user
|
|
742
|
+
* already has work in flight vs. a competing contributor.
|
|
743
|
+
*/
|
|
744
|
+
linkedPRClassification?: 'none' | 'user_open' | 'user_closed' | 'user_merged' | 'other_open' | 'other_closed' | 'other_merged';
|
|
745
|
+
/**
|
|
746
|
+
* Optional SLM pre-triage classification (#1122). Populated when the
|
|
747
|
+
* user has set `slmTriageModel` and a local Ollama instance answered
|
|
748
|
+
* within the timeout. `null` otherwise.
|
|
749
|
+
*/
|
|
750
|
+
slmTriage?: {
|
|
751
|
+
decision: 'pursue' | 'investigate' | 'skip';
|
|
752
|
+
confidence: 'high' | 'medium' | 'low';
|
|
753
|
+
reasons: string[];
|
|
754
|
+
modelVersion: string;
|
|
755
|
+
} | null;
|
|
728
756
|
/** Success-likelihood grade (#858): predicts whether a PR will merge. */
|
|
729
757
|
grade: {
|
|
730
758
|
letter: 'A' | 'B' | 'C' | 'F';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oss-autopilot/core",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "CLI and core library for managing open source contributions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -54,18 +54,18 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
56
56
|
"@octokit/rest": "^22.0.1",
|
|
57
|
-
"@oss-scout/core": "^0.
|
|
57
|
+
"@oss-scout/core": "^0.7.1",
|
|
58
58
|
"commander": "^14.0.3",
|
|
59
59
|
"zod": "^4.3.6"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^25.
|
|
63
|
-
"@vitest/coverage-v8": "^4.1.
|
|
64
|
-
"esbuild": "^0.
|
|
62
|
+
"@types/node": "^25.6.0",
|
|
63
|
+
"@vitest/coverage-v8": "^4.1.5",
|
|
64
|
+
"esbuild": "^0.28.0",
|
|
65
65
|
"tsx": "^4.21.0",
|
|
66
|
-
"typedoc": "^0.28.
|
|
66
|
+
"typedoc": "^0.28.19",
|
|
67
67
|
"typescript": "^5.9.3",
|
|
68
|
-
"vitest": "^4.1.
|
|
68
|
+
"vitest": "^4.1.5"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsc",
|