openclaw-llm-verifier 0.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/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/verifier.js +246 -0
- package/dist/verifier.js.map +1 -0
- package/openclaw.plugin.json +31 -0
- package/package.json +47 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw plugin entry point (constitution IV: Protocol Compliance).
|
|
3
|
+
*
|
|
4
|
+
* Uses definePluginEntry from openclaw/plugin-sdk/plugin-entry per the
|
|
5
|
+
* building-plugins specification (https://docs.openclaw.ai/zh-CN/plugins/building-plugins).
|
|
6
|
+
* Registers two tools: `score` (US1/US2) and `select` (US3).
|
|
7
|
+
*/
|
|
8
|
+
import { Type } from "typebox";
|
|
9
|
+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
10
|
+
import { createGeminiClient, selectBest, scoreAllTrials, scorePairCriterion, } from "./verifier.js";
|
|
11
|
+
const ScoreParams = Type.Object({
|
|
12
|
+
problem: Type.String({ description: "Task description" }),
|
|
13
|
+
traceA: Type.String({ description: "Trajectory A text" }),
|
|
14
|
+
traceB: Type.String({ description: "Trajectory B text" }),
|
|
15
|
+
criterion: Type.Object({
|
|
16
|
+
id: Type.String(),
|
|
17
|
+
name: Type.String(),
|
|
18
|
+
description: Type.String(),
|
|
19
|
+
}),
|
|
20
|
+
groundTruthNote: Type.String(),
|
|
21
|
+
});
|
|
22
|
+
const SelectParams = Type.Object({
|
|
23
|
+
taskName: Type.String(),
|
|
24
|
+
trials: Type.Array(Type.Object({
|
|
25
|
+
trialName: Type.String(),
|
|
26
|
+
reward: Type.Number(),
|
|
27
|
+
problem: Type.String(),
|
|
28
|
+
trace: Type.String(),
|
|
29
|
+
})),
|
|
30
|
+
criteria: Type.Array(Type.Object({
|
|
31
|
+
id: Type.String(),
|
|
32
|
+
name: Type.String(),
|
|
33
|
+
description: Type.String(),
|
|
34
|
+
})),
|
|
35
|
+
groundTruthNote: Type.String(),
|
|
36
|
+
nReps: Type.Optional(Type.Number()),
|
|
37
|
+
});
|
|
38
|
+
export default definePluginEntry({
|
|
39
|
+
id: "openclaw-llm-verifier",
|
|
40
|
+
name: "LLM-as-a-Verifier",
|
|
41
|
+
description: "Call-chain verification with logprob-based scoring, per-call " +
|
|
42
|
+
"tracking, and cached re-scoring.",
|
|
43
|
+
register(api) {
|
|
44
|
+
let client = null;
|
|
45
|
+
function getClient() {
|
|
46
|
+
if (!client) {
|
|
47
|
+
client = createGeminiClient();
|
|
48
|
+
}
|
|
49
|
+
return client;
|
|
50
|
+
}
|
|
51
|
+
api.registerTool({
|
|
52
|
+
name: "score",
|
|
53
|
+
label: "Score",
|
|
54
|
+
description: "Score a trajectory pair on one criterion. Returns normalized " +
|
|
55
|
+
"scoreA, scoreB in [0,1] derived from Gemini logprobs.",
|
|
56
|
+
parameters: ScoreParams,
|
|
57
|
+
async execute(_toolCallId, params, _signal, _onUpdate) {
|
|
58
|
+
const c = getClient();
|
|
59
|
+
const [scoreA, scoreB] = await scorePairCriterion(c, params.problem, params.traceA, params.traceB, params.criterion, params.groundTruthNote);
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: JSON.stringify({ scoreA, scoreB }),
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
details: { scoreA, scoreB },
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
api.registerTool({
|
|
72
|
+
name: "select",
|
|
73
|
+
label: "Select",
|
|
74
|
+
description: "Select the best trial via round-robin tournament scoring. " +
|
|
75
|
+
"Batch-scores all pairs on all criteria, then picks the trial " +
|
|
76
|
+
"with the most wins.",
|
|
77
|
+
parameters: SelectParams,
|
|
78
|
+
async execute(_toolCallId, params, _signal, _onUpdate) {
|
|
79
|
+
const c = getClient();
|
|
80
|
+
const nReps = params.nReps ?? 4;
|
|
81
|
+
const tasks = {
|
|
82
|
+
[params.taskName]: params.trials,
|
|
83
|
+
};
|
|
84
|
+
const criteria = params.criteria;
|
|
85
|
+
const scores = await scoreAllTrials(c, tasks, [params.taskName], criteria, params.groundTruthNote, nReps);
|
|
86
|
+
const sel = selectBest(tasks, [params.taskName], scores, criteria.map((cr) => cr.id), nReps);
|
|
87
|
+
return {
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: "text",
|
|
91
|
+
text: JSON.stringify({
|
|
92
|
+
bestTrial: sel[params.taskName].trial,
|
|
93
|
+
scores,
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
details: {
|
|
98
|
+
bestTrial: sel[params.taskName].trial,
|
|
99
|
+
scores,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/verifier.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifier core logic, ported from scripts/verifier_core.py (Python).
|
|
3
|
+
*
|
|
4
|
+
* Constitution III (Verifier Parity, NON-NEGOTIABLE): this TypeScript
|
|
5
|
+
* port MUST reproduce the Python source's numeric behavior exactly.
|
|
6
|
+
* Constitution VI (Source-Faithful Port): naming, constants, and data
|
|
7
|
+
* shapes carry over verbatim (snake_case -> camelCase only where TS
|
|
8
|
+
* convention requires).
|
|
9
|
+
*
|
|
10
|
+
* DEVIATION (constitution VI scope note): the Python source's fallback
|
|
11
|
+
* patterns (extract_score returning 0.5 on parse failure, score_all_trials
|
|
12
|
+
* writing 0.5/0.5 on exception) are NOT carried over. Errors propagate.
|
|
13
|
+
*/
|
|
14
|
+
import { GoogleGenAI } from "@google/genai";
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// g=20 scoring scale (mirrors source GRANULARITY + SCALE)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
export const GRANULARITY = 20;
|
|
19
|
+
const VALID_TOKENS = {};
|
|
20
|
+
for (let i = 0; i < GRANULARITY; i++) {
|
|
21
|
+
VALID_TOKENS[String.fromCharCode(65 + i)] = GRANULARITY - i; // A-T
|
|
22
|
+
VALID_TOKENS[String.fromCharCode(97 + i)] = GRANULARITY - i; // a-t
|
|
23
|
+
}
|
|
24
|
+
export const SCALE = {
|
|
25
|
+
scaleDescription: "Rate how likely the agent correctly solved the task on a " +
|
|
26
|
+
"20-point scale using letters A through T:\n" +
|
|
27
|
+
" A = clearly and completely succeeded with verified output (best)\n" +
|
|
28
|
+
" B-D = succeeded with only minor issues\n" +
|
|
29
|
+
" E-G = above average, mostly correct with some issues\n" +
|
|
30
|
+
" H-J = uncertain, leans toward success\n" +
|
|
31
|
+
" K-M = uncertain, leans toward failure\n" +
|
|
32
|
+
" N-P = below average, significant issues remain\n" +
|
|
33
|
+
" Q-S = failed with some partial progress\n" +
|
|
34
|
+
" T = clearly and completely failed (worst)",
|
|
35
|
+
scoreFormat: "LETTER_A_TO_T",
|
|
36
|
+
validTokens: VALID_TOKENS,
|
|
37
|
+
};
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Errors
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
export class ScoreExtractionError extends Error {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = "ScoreExtractionError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Gemini client
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
export function createGeminiClient() {
|
|
51
|
+
const vertexKey = process.env.VERTEX_API_KEY;
|
|
52
|
+
if (vertexKey) {
|
|
53
|
+
return new GoogleGenAI({ vertexai: true, apiKey: vertexKey });
|
|
54
|
+
}
|
|
55
|
+
const apiKey = process.env.GEMINI_API_KEY;
|
|
56
|
+
if (apiKey) {
|
|
57
|
+
return new GoogleGenAI({ apiKey });
|
|
58
|
+
}
|
|
59
|
+
throw new Error("set GEMINI_API_KEY or VERTEX_API_KEY in environment");
|
|
60
|
+
}
|
|
61
|
+
export async function callGemini(client, prompt, topLogprobs = 20) {
|
|
62
|
+
const response = await client.models.generateContent({
|
|
63
|
+
model: "gemini-2.5-flash",
|
|
64
|
+
contents: [{ role: "user", parts: [{ text: prompt }] }],
|
|
65
|
+
config: {
|
|
66
|
+
maxOutputTokens: 4096,
|
|
67
|
+
temperature: 1.0,
|
|
68
|
+
responseLogprobs: true,
|
|
69
|
+
logprobs: topLogprobs,
|
|
70
|
+
thinkingConfig: { thinkingBudget: 0 },
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
const text = response.text ?? "";
|
|
74
|
+
const candidate = response.candidates?.[0];
|
|
75
|
+
const logprobsResult = candidate?.logprobsResult;
|
|
76
|
+
let tokens = null;
|
|
77
|
+
let positionLogprobs = null;
|
|
78
|
+
if (logprobsResult?.topCandidates) {
|
|
79
|
+
positionLogprobs = logprobsResult.topCandidates.map((pos) => (pos.candidates ?? []).map((lp) => [lp.token ?? "", lp.logProbability ?? 0]));
|
|
80
|
+
if (logprobsResult.chosenCandidates) {
|
|
81
|
+
tokens = logprobsResult.chosenCandidates.map((c) => c.token ?? "");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { text, tokens, positionLogprobs };
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Score extraction (logprob path, NO fallback)
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
export function findTagLogprobs(tokens, positionLogprobs, tag) {
|
|
90
|
+
if (!tokens || !positionLogprobs)
|
|
91
|
+
return null;
|
|
92
|
+
let textSoFar = "";
|
|
93
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
94
|
+
textSoFar += tokens[i];
|
|
95
|
+
if (textSoFar.trimEnd().endsWith(tag)) {
|
|
96
|
+
if (i + 1 < positionLogprobs.length) {
|
|
97
|
+
return positionLogprobs[i + 1];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
export function extractScoreStrict(text, tokens, positionLogprobs, tag) {
|
|
104
|
+
const validTokens = SCALE.validTokens;
|
|
105
|
+
const tagLp = findTagLogprobs(tokens, positionLogprobs, tag);
|
|
106
|
+
const probs = {};
|
|
107
|
+
if (tagLp) {
|
|
108
|
+
for (const [tokStr, logprob] of tagLp) {
|
|
109
|
+
const tok = tokStr.trim();
|
|
110
|
+
if (tok in validTokens) {
|
|
111
|
+
const val = validTokens[tok];
|
|
112
|
+
const p = Math.exp(logprob);
|
|
113
|
+
probs[val] = Math.max(probs[val] ?? 0, p);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const probEntries = Object.entries(probs);
|
|
118
|
+
if (probEntries.length > 0) {
|
|
119
|
+
const uniqueVals = [...new Set(Object.values(validTokens))].sort((a, b) => a - b);
|
|
120
|
+
const minVal = uniqueVals[0];
|
|
121
|
+
const maxVal = uniqueVals[uniqueVals.length - 1];
|
|
122
|
+
const totalP = Object.values(probs).reduce((s, p) => s + p, 0);
|
|
123
|
+
const expected = probEntries.reduce((s, [v, p]) => s + Number(v) * p, 0) / totalP;
|
|
124
|
+
return maxVal > minVal
|
|
125
|
+
? (expected - minVal) / (maxVal - minVal)
|
|
126
|
+
: 0.5;
|
|
127
|
+
}
|
|
128
|
+
// DEVIATION (constitution VI scope note): source returns 0.5 here;
|
|
129
|
+
// we throw instead.
|
|
130
|
+
throw new ScoreExtractionError(`no valid score tokens at tag ${tag} (logprob path empty)`);
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Pairwise prompt + scoring
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
export function createPromptForCriterion(problem, traceA, traceB, criterion, groundTruthNote) {
|
|
136
|
+
return ("You are an expert evaluator of AI coding agents. " +
|
|
137
|
+
"You will see a task description and two agent trajectories. " +
|
|
138
|
+
`Your job is to evaluate them on ONE specific criterion: ` +
|
|
139
|
+
`**${criterion.name}**.\n\n` +
|
|
140
|
+
`${groundTruthNote}\n\n` +
|
|
141
|
+
`**Task:**\n${problem}\n\n` +
|
|
142
|
+
`**Trajectory A:**\n${traceA}\n\n` +
|
|
143
|
+
`**Trajectory B:**\n${traceB}\n\n` +
|
|
144
|
+
`**Evaluation Guideline — ${criterion.name}:**\n` +
|
|
145
|
+
`${criterion.description}\n\n` +
|
|
146
|
+
`Score each trajectory ONLY on this specific criterion. Ignore other ` +
|
|
147
|
+
`aspects of the trajectory that are not relevant to ` +
|
|
148
|
+
`"${criterion.name}".\n\n` +
|
|
149
|
+
`**Rating Scale:**\n${SCALE.scaleDescription}\n\n` +
|
|
150
|
+
"Then output your final scores:\n" +
|
|
151
|
+
`<score_A>${SCALE.scoreFormat}</score_A>\n` +
|
|
152
|
+
`<score_B>${SCALE.scoreFormat}</score_B>\n\n` +
|
|
153
|
+
"Begin your analysis now.");
|
|
154
|
+
}
|
|
155
|
+
export async function scorePairCriterion(client, problem, traceA, traceB, criterion, groundTruthNote) {
|
|
156
|
+
const prompt = createPromptForCriterion(problem, traceA, traceB, criterion, groundTruthNote);
|
|
157
|
+
const { text, tokens, positionLogprobs } = await callGemini(client, prompt);
|
|
158
|
+
const sa = extractScoreStrict(text, tokens, positionLogprobs, "<score_A>");
|
|
159
|
+
const sb = extractScoreStrict(text, tokens, positionLogprobs, "<score_B>");
|
|
160
|
+
return [sa, sb];
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Batch scoring (no try/catch -> 0.5 fallback; errors propagate)
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
export async function scoreAllTrials(client, tasks, swingTasks, criteria, groundTruthNote, nReps, cache = {}) {
|
|
166
|
+
const cached = { ...cache };
|
|
167
|
+
const jobs = [];
|
|
168
|
+
for (const taskName of swingTasks) {
|
|
169
|
+
const trials = tasks[taskName];
|
|
170
|
+
const n = trials.length;
|
|
171
|
+
for (let i = 0; i < n; i++) {
|
|
172
|
+
for (let j = i + 1; j < n; j++) {
|
|
173
|
+
for (const crit of criteria) {
|
|
174
|
+
for (let rep = 0; rep < nReps; rep++) {
|
|
175
|
+
const key = `${crit.id}|${taskName}|${i},${j}|${rep}`;
|
|
176
|
+
if (!(key in cached)) {
|
|
177
|
+
jobs.push({ key, trialI: trials[i], trialJ: trials[j], crit });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// DEVIATION: source catches per-pair exceptions and writes 0.5/0.5.
|
|
185
|
+
// We let errors propagate (constitution no-fallback).
|
|
186
|
+
const results = await Promise.all(jobs.map(async (job) => {
|
|
187
|
+
const [sa, sb] = await scorePairCriterion(client, job.trialI.problem, job.trialI.trace, job.trialJ.trace, job.crit, groundTruthNote);
|
|
188
|
+
return { key: job.key, scoreI: sa, scoreJ: sb };
|
|
189
|
+
}));
|
|
190
|
+
for (const r of results) {
|
|
191
|
+
cached[r.key] = { scoreI: r.scoreI, scoreJ: r.scoreJ };
|
|
192
|
+
}
|
|
193
|
+
return cached;
|
|
194
|
+
}
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Tournament selection
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
export function selectBest(tasks, swingTasks, scores, criteriaIds, nReps = 1, repIdx = null) {
|
|
199
|
+
const selections = {};
|
|
200
|
+
for (const taskName of swingTasks) {
|
|
201
|
+
const trials = tasks[taskName];
|
|
202
|
+
const n = trials.length;
|
|
203
|
+
const wins = new Array(n).fill(0);
|
|
204
|
+
for (let i = 0; i < n; i++) {
|
|
205
|
+
for (let j = i + 1; j < n; j++) {
|
|
206
|
+
let siSum = 0;
|
|
207
|
+
let sjSum = 0;
|
|
208
|
+
let count = 0;
|
|
209
|
+
for (const cid of criteriaIds) {
|
|
210
|
+
const reps = repIdx !== null
|
|
211
|
+
? [repIdx]
|
|
212
|
+
: Array.from({ length: nReps }, (_, k) => k);
|
|
213
|
+
for (const rep of reps) {
|
|
214
|
+
const key = `${cid}|${taskName}|${i},${j}|${rep}`;
|
|
215
|
+
const entry = scores[key] ?? { scoreI: 0.5, scoreJ: 0.5 };
|
|
216
|
+
siSum += entry.scoreI;
|
|
217
|
+
sjSum += entry.scoreJ;
|
|
218
|
+
count++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const si = count ? siSum / count : 0.5;
|
|
222
|
+
const sj = count ? sjSum / count : 0.5;
|
|
223
|
+
if (si > sj)
|
|
224
|
+
wins[i] += 1;
|
|
225
|
+
else if (sj > si)
|
|
226
|
+
wins[j] += 1;
|
|
227
|
+
else {
|
|
228
|
+
wins[i] += 0.5;
|
|
229
|
+
wins[j] += 0.5;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
let bestIdx = 0;
|
|
234
|
+
for (let t = 1; t < n; t++) {
|
|
235
|
+
if (wins[t] > wins[bestIdx])
|
|
236
|
+
bestIdx = t;
|
|
237
|
+
}
|
|
238
|
+
selections[taskName] = {
|
|
239
|
+
idx: bestIdx,
|
|
240
|
+
trial: trials[bestIdx].trialName,
|
|
241
|
+
reward: trials[bestIdx].reward,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return selections;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "openclaw-llm-verifier",
|
|
3
|
+
"name": "LLM-as-a-Verifier",
|
|
4
|
+
"description": "Call-chain verification with logprob-based scoring, per-call tracking, and cached re-scoring. Scores trajectory pairs on criteria via Gemini 2.5 Flash logprobs, runs round-robin tournament selection.",
|
|
5
|
+
"contracts": {
|
|
6
|
+
"tools": ["score", "select"]
|
|
7
|
+
},
|
|
8
|
+
"activation": {
|
|
9
|
+
"onStartup": false
|
|
10
|
+
},
|
|
11
|
+
"configSchema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"geminiApiKey": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Gemini API key (or set GEMINI_API_KEY / VERTEX_API_KEY env var)"
|
|
18
|
+
},
|
|
19
|
+
"granularity": {
|
|
20
|
+
"type": "number",
|
|
21
|
+
"default": 20,
|
|
22
|
+
"description": "Scoring granularity (g=20: A-T tokens)"
|
|
23
|
+
},
|
|
24
|
+
"nReps": {
|
|
25
|
+
"type": "number",
|
|
26
|
+
"default": 4,
|
|
27
|
+
"description": "Number of repeated verifications per pair"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-llm-verifier",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "OpenClaw plugin: call-chain verification with logprob-based scoring, per-call tracking, and cached re-scoring.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "ninetyhe",
|
|
8
|
+
"keywords": ["openclaw", "plugin", "verifier", "llm", "gemini", "logprobs", "scoring"],
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"openclaw.plugin.json"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/ninetyhe-90/openclaw-llm-verifier"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/ninetyhe-90/openclaw-llm-verifier",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/ninetyhe-90/openclaw-llm-verifier/issues"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@google/genai": "^1.0.0",
|
|
23
|
+
"typebox": "^1.1.39"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"openclaw": ">=2026.3.24-beta.2"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"typescript": "^5.5.0",
|
|
30
|
+
"vitest": "^2.0.0"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"test": "vitest run"
|
|
35
|
+
},
|
|
36
|
+
"openclaw": {
|
|
37
|
+
"extensions": ["./dist/index.js"],
|
|
38
|
+
"compat": {
|
|
39
|
+
"pluginApi": ">=2026.3.24-beta.2",
|
|
40
|
+
"minGatewayVersion": "2026.3.24-beta.2"
|
|
41
|
+
},
|
|
42
|
+
"build": {
|
|
43
|
+
"openclawVersion": "2026.3.24-beta.2",
|
|
44
|
+
"pluginSdkVersion": "2026.3.24-beta.2"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|