@orangekame3/pi-qcaleval 0.0.2-beta.3 → 0.0.2-beta.5
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/README.md +8 -1
- package/extensions/qcaleval.ts +39 -10
- package/package.json +1 -1
- package/skills/qcaleval/SKILL.md +4 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ works from the pi CLI and from the QDash Copilot runtime alike.
|
|
|
13
13
|
|
|
14
14
|
## Tool
|
|
15
15
|
|
|
16
|
-
`qcal_evaluate(context, question?, images?, max_images?)` returns a JSON object with
|
|
16
|
+
`qcal_evaluate(context, question?, task_name?, knowledge?, images?, max_images?)` returns a JSON object with
|
|
17
17
|
`technical_description`, `experimental_conclusion`, `experimental_significance`,
|
|
18
18
|
`fit_quality`, `parameter_extraction`, and `success`. The parsed object is also
|
|
19
19
|
stored in the tool result's `details.diagnosis`; when the model did not answer
|
|
@@ -24,6 +24,13 @@ figures of the conversation, so the planner does not have to pass image bytes;
|
|
|
24
24
|
`max_images` (default 1, up to 4) says how many of the newest figures to supply,
|
|
25
25
|
for example 2 when an expected reference figure precedes the measured result.
|
|
26
26
|
|
|
27
|
+
`knowledge` is the host's reference for the experiment: what a good result
|
|
28
|
+
looks like, the questions a reviewer asks, and the common failure patterns. A
|
|
29
|
+
host that keeps such knowledge per task fills it in from `task_name`, so the
|
|
30
|
+
planner only names the task; the text is sent before the context. The exact
|
|
31
|
+
user turn the model received (reference, context, question) is stored in
|
|
32
|
+
`details.prompt`, so a host can show what the model saw.
|
|
33
|
+
|
|
27
34
|
## Configuration
|
|
28
35
|
|
|
29
36
|
No setting is required. The evaluation model is resolved in this order:
|
package/extensions/qcaleval.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* pi-qcaleval: evaluate calibration plots with a dedicated calibration VLM.
|
|
3
3
|
*
|
|
4
4
|
* The extension has no QDash dependency. It takes a plot (plus the experiment
|
|
5
|
-
* context the planner already knows
|
|
5
|
+
* context the planner already knows, and the host's reference knowledge for
|
|
6
|
+
* the task when the host supplies one) and asks the evaluation model, which is
|
|
6
7
|
* configured separately from the conversation's model, for a diagnosis. The
|
|
7
8
|
* planner decides what to do with it; whether a calibration loop continues is
|
|
8
9
|
* the host's policy, not this tool's.
|
|
@@ -109,20 +110,31 @@ export const SYSTEM_PROMPT = [
|
|
|
109
110
|
' "fit_quality": "good" | "marginal" | "poor" and why;',
|
|
110
111
|
' "parameter_extraction": extracted values with units, or null;',
|
|
111
112
|
' "success": true | false, whether the experiment achieved its goal.',
|
|
112
|
-
"Base every statement on the plot and the given context only.",
|
|
113
|
+
"Base every statement on the plot, the reference, and the given context only.",
|
|
113
114
|
].join("\n");
|
|
114
115
|
|
|
115
116
|
/**
|
|
116
|
-
* Build the single user turn sent to the evaluation model.
|
|
117
|
-
*
|
|
118
|
-
*
|
|
117
|
+
* Build the single user turn sent to the evaluation model. The host's
|
|
118
|
+
* reference for the task, when given, comes first so the context and the plot
|
|
119
|
+
* are read against it. With several figures, the model is told how many follow
|
|
120
|
+
* so it reads them in the order the context describes (expected reference
|
|
121
|
+
* first, measured result last).
|
|
119
122
|
*/
|
|
120
123
|
export function buildUserPrompt(
|
|
121
124
|
context: string,
|
|
122
125
|
question: string | undefined,
|
|
123
126
|
imageCount = 1,
|
|
127
|
+
knowledge?: string,
|
|
124
128
|
): string {
|
|
125
|
-
const lines = [
|
|
129
|
+
const lines: string[] = [];
|
|
130
|
+
if (knowledge?.trim()) {
|
|
131
|
+
lines.push(
|
|
132
|
+
"Reference for this experiment (expected result, review questions, failure patterns):",
|
|
133
|
+
knowledge.trim(),
|
|
134
|
+
"",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
lines.push("Experiment context:", context.trim() || "(none)");
|
|
126
138
|
if (imageCount > 1) {
|
|
127
139
|
lines.push(
|
|
128
140
|
"",
|
|
@@ -130,6 +142,9 @@ export function buildUserPrompt(
|
|
|
130
142
|
);
|
|
131
143
|
}
|
|
132
144
|
if (question?.trim()) lines.push("", "Specific question:", question.trim());
|
|
145
|
+
// Repeated here because a long reference ahead of the plot pulls the model
|
|
146
|
+
// towards prose; the last instruction it reads is the output format.
|
|
147
|
+
lines.push("", "Answer with the JSON object described in the system prompt, and nothing else.");
|
|
133
148
|
return lines.join("\n");
|
|
134
149
|
}
|
|
135
150
|
|
|
@@ -199,6 +214,18 @@ const parameters = Type.Object({
|
|
|
199
214
|
question: Type.Optional(
|
|
200
215
|
Type.String({ description: "A specific question to answer about the plot" }),
|
|
201
216
|
),
|
|
217
|
+
task_name: Type.Optional(
|
|
218
|
+
Type.String({
|
|
219
|
+
description:
|
|
220
|
+
"The calibration task's name as the host knows it (e.g. RandomizedBenchmarking). Lets the host supply its reference knowledge for the experiment.",
|
|
221
|
+
}),
|
|
222
|
+
),
|
|
223
|
+
knowledge: Type.Optional(
|
|
224
|
+
Type.String({
|
|
225
|
+
description:
|
|
226
|
+
"Normally omitted: the host supplies the reference for `task_name` (expected result, review questions, failure patterns). Fill only to override it with text you were given.",
|
|
227
|
+
}),
|
|
228
|
+
),
|
|
202
229
|
images: Type.Optional(
|
|
203
230
|
Type.Array(imageSchema, {
|
|
204
231
|
description:
|
|
@@ -224,6 +251,8 @@ export interface EvaluationDetails {
|
|
|
224
251
|
diagnosis?: Record<string, unknown> | null;
|
|
225
252
|
/** The model's answer when it was not the requested JSON. */
|
|
226
253
|
raw?: string;
|
|
254
|
+
/** The user turn the model was sent (reference, context, question), so the host can show what it saw. */
|
|
255
|
+
prompt?: string;
|
|
227
256
|
}
|
|
228
257
|
|
|
229
258
|
function failure(spec: ModelSpec | undefined, text: string): AgentToolResult<EvaluationDetails> {
|
|
@@ -244,6 +273,7 @@ export default function qcalevalExtension(pi: ExtensionAPI) {
|
|
|
244
273
|
promptGuidelines: [
|
|
245
274
|
"Use qcal_evaluate for every calibration figure you need to judge, instead of judging it yourself.",
|
|
246
275
|
"Pass the task name, target, and expected result as context so the diagnosis is specific.",
|
|
276
|
+
"Pass task_name when you know it: the host then supplies its reference knowledge for that task.",
|
|
247
277
|
"Treat the returned diagnosis as the evaluation of record; add your own reasoning only on top of it.",
|
|
248
278
|
],
|
|
249
279
|
parameters,
|
|
@@ -267,6 +297,7 @@ export default function qcalevalExtension(pi: ExtensionAPI) {
|
|
|
267
297
|
return failure(spec, "no plot was given. Pass the figure in `images` or fetch it first.");
|
|
268
298
|
}
|
|
269
299
|
|
|
300
|
+
const prompt = buildUserPrompt(params.context, params.question, images.length, params.knowledge);
|
|
270
301
|
const message = await ctx.modelRegistry.complete(
|
|
271
302
|
model,
|
|
272
303
|
{
|
|
@@ -275,10 +306,7 @@ export default function qcalevalExtension(pi: ExtensionAPI) {
|
|
|
275
306
|
{
|
|
276
307
|
role: "user",
|
|
277
308
|
content: [
|
|
278
|
-
{
|
|
279
|
-
type: "text",
|
|
280
|
-
text: buildUserPrompt(params.context, params.question, images.length),
|
|
281
|
-
},
|
|
309
|
+
{ type: "text", text: prompt },
|
|
282
310
|
...images,
|
|
283
311
|
],
|
|
284
312
|
timestamp: Date.now(),
|
|
@@ -299,6 +327,7 @@ export default function qcalevalExtension(pi: ExtensionAPI) {
|
|
|
299
327
|
...(fallback ? { fallback: true } : {}),
|
|
300
328
|
diagnosis: diagnosis ?? null,
|
|
301
329
|
...(diagnosis ? {} : { raw: text }),
|
|
330
|
+
prompt,
|
|
302
331
|
},
|
|
303
332
|
...(message.usage ? { usage: message.usage } : {}),
|
|
304
333
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orangekame3/pi-qcaleval",
|
|
3
|
-
"version": "0.0.2-beta.
|
|
3
|
+
"version": "0.0.2-beta.5",
|
|
4
4
|
"description": "pi extension that sends calibration plots to a calibration-evaluation VLM such as NVIDIA Ising-Calibration and returns a structured diagnosis",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
package/skills/qcaleval/SKILL.md
CHANGED
|
@@ -18,6 +18,10 @@ Ising-Calibration by default) and returns a JSON diagnosis with
|
|
|
18
18
|
the task name, the target (qubit or coupling), the swept parameter, and what a
|
|
19
19
|
successful result looks like. Add `question` when a specific point matters
|
|
20
20
|
(for example "is the chevron centred on the current frequency?").
|
|
21
|
+
- Pass `task_name` whenever you know the task (for example `CheckRabi`): the
|
|
22
|
+
host then supplies its own reference knowledge for that experiment, which is
|
|
23
|
+
more reliable than a summary you write yourself. Keep `context` for what the
|
|
24
|
+
reference cannot know: the target, the swept range, and previous values.
|
|
21
25
|
- When the conversation holds an expected reference figure followed by the
|
|
22
26
|
measured result (a task review opens this way), pass `max_images: 2` and say
|
|
23
27
|
in `context` that the first figure is the reference and the last the
|