@oqtopus-team/pi-qdash 0.1.10-beta.15 → 0.1.10

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.
@@ -75,9 +75,6 @@ type QDashQueryParams = {
75
75
  | "flow_helper_file"
76
76
  | "executions"
77
77
  | "execution"
78
- | "ai_reviews"
79
- | "ai_review_runs"
80
- | "ai_review_run"
81
78
  | "forum_posts"
82
79
  | "provenance_stats"
83
80
  | "provenance_history"
@@ -98,7 +95,6 @@ type QDashQueryParams = {
98
95
  templateId?: string;
99
96
  filename?: string;
100
97
  executionId?: string;
101
- reviewRunId?: string;
102
98
  entityId?: string;
103
99
  parameter?: string;
104
100
  parameterName?: string;
@@ -106,7 +102,6 @@ type QDashQueryParams = {
106
102
  date?: string;
107
103
  backend?: string;
108
104
  status?: string;
109
- decision?: string;
110
105
  username?: string;
111
106
  messageContains?: string;
112
107
  startAt?: string;
@@ -114,7 +109,6 @@ type QDashQueryParams = {
114
109
  startFrom?: string;
115
110
  startTo?: string;
116
111
  isClosed?: boolean;
117
- latestOnly?: boolean;
118
112
  withinHours?: number;
119
113
  limit?: number;
120
114
  skip?: number;
@@ -323,9 +317,6 @@ const QueryAction = Type.Union([
323
317
  Type.Literal("flow_helper_file"),
324
318
  Type.Literal("executions"),
325
319
  Type.Literal("execution"),
326
- Type.Literal("ai_reviews"),
327
- Type.Literal("ai_review_runs"),
328
- Type.Literal("ai_review_run"),
329
320
  Type.Literal("forum_posts"),
330
321
  Type.Literal("provenance_stats"),
331
322
  Type.Literal("provenance_history"),
@@ -367,7 +358,6 @@ const querySchema = Type.Object({
367
358
  templateId: Type.Optional(Type.String()),
368
359
  filename: Type.Optional(Type.String()),
369
360
  executionId: Type.Optional(Type.String()),
370
- reviewRunId: Type.Optional(Type.String()),
371
361
  entityId: Type.Optional(Type.String()),
372
362
  parameter: Type.Optional(Type.String({ description: "Metric/parameter name for timeseries." })),
373
363
  parameterName: Type.Optional(Type.String()),
@@ -375,7 +365,6 @@ const querySchema = Type.Object({
375
365
  date: Type.Optional(Type.String({ description: "History date, usually YYYYMMDD." })),
376
366
  backend: Type.Optional(Type.String()),
377
367
  status: Type.Optional(Type.String()),
378
- decision: Type.Optional(Type.String()),
379
368
  username: Type.Optional(Type.String()),
380
369
  messageContains: Type.Optional(Type.String()),
381
370
  startAt: Type.Optional(Type.String()),
@@ -383,7 +372,6 @@ const querySchema = Type.Object({
383
372
  startFrom: Type.Optional(Type.String()),
384
373
  startTo: Type.Optional(Type.String()),
385
374
  isClosed: Type.Optional(Type.Boolean()),
386
- latestOnly: Type.Optional(Type.Boolean()),
387
375
  withinHours: Type.Optional(Type.Number()),
388
376
  limit: Type.Optional(Type.Number()),
389
377
  skip: Type.Optional(Type.Number()),
@@ -466,7 +454,7 @@ function qcalEvidenceText(evidence: CalibrationEvidence): string {
466
454
  `Figures ${figures.length}`,
467
455
  ...figures.map((figure, index) => ` - #${index + 1} ${String(figure.role ?? "plot")} ${String(figure.path ?? figure.url ?? "")}`),
468
456
  "",
469
- "Use qcal_evaluate_bundle with details.evidence to evaluate this evidence with pi-qcal.",
457
+ "Pass this summary as the context of qcal_evaluate; the embedded figure is the measured result to judge.",
470
458
  ]).join("\n");
471
459
  }
472
460
 
@@ -1252,12 +1240,11 @@ async function buildDashboardInsights(params: { profile?: string; configPath?: s
1252
1240
  const limit = params.limit ?? 30;
1253
1241
  const end = new Date();
1254
1242
  const start = new Date(end.getTime() - (params.withinHours ?? 168) * 3600_000);
1255
- const [forums, issues, failed, metrics, aiInsights] = await Promise.allSettled([
1243
+ const [forums, issues, failed, metrics] = await Promise.allSettled([
1256
1244
  client.listForumPosts({ chipId, status: "open", limit }),
1257
1245
  client.api.listIssues({ is_closed: false, limit }),
1258
1246
  client.api.listTaskResults({ chip_id: chipId, status: "failed", start_from: start.toISOString(), start_to: end.toISOString(), limit }),
1259
1247
  client.getChipMetrics(chipId),
1260
- client.api.getDashboardAiInsights(chipId, { latest_only: true, start_at: start.toISOString(), end_at: end.toISOString() }),
1261
1248
  ]);
1262
1249
  const value = <T>(result: PromiseSettledResult<T>): T | undefined => result.status === "fulfilled" ? result.value : undefined;
1263
1250
  const insightMap = new Map<string, DashboardInsight>();
@@ -1289,20 +1276,6 @@ async function buildDashboardInsights(params: { profile?: string; configPath?: s
1289
1276
 
1290
1277
  addMetricInsights(insightMap, value(metrics), client);
1291
1278
 
1292
- const aiPayload = value(aiInsights);
1293
- for (const item of arrayFromPayload(aiPayload).filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === "object")) {
1294
- const title = firstString(item, ["title", "summary"]) ?? "QDash AI insight";
1295
- const severityValue = firstString(item, ["severity"])?.toLowerCase();
1296
- const severity: DashboardInsight["severity"] = severityValue === "critical" ? "critical" : severityValue === "warning" ? "warning" : "info";
1297
- const targets = Array.isArray(item.affected_targets) ? item.affected_targets.filter((target): target is string => typeof target === "string") : [];
1298
- for (const rawTarget of targets) {
1299
- const target = rawTarget.match(/^Q/i) ? `q${rawTarget.replace(/^Q0*/i, "")}` : rawTarget.match(/^C/i) ? `c${rawTarget.slice(1)}` : targetFromText(rawTarget);
1300
- if (!target) continue;
1301
- const evidence = firstString(item, ["recommended_action", "primary_reason"]) ?? `QDash AI insight: ${title}`;
1302
- addEvidence(insightMap, target, severity, title, evidence, firstString(item, ["recommended_action"]) ?? "Review the QDash AI insight and supporting task evidence.");
1303
- }
1304
- }
1305
-
1306
1279
  const insights = [...insightMap.values()].sort((a, b) => {
1307
1280
  const rank = { critical: 2, warning: 1, info: 0 } as const;
1308
1281
  return rank[b.severity] - rank[a.severity] || b.evidence.length - a.evidence.length;
@@ -1515,9 +1488,6 @@ async function executeQuery(params: QDashQueryParams) {
1515
1488
  case "flow_helper_file": return client.api.getFlowHelperFile(requireValue(params.filename, "filename"));
1516
1489
  case "executions": return rawGet(client, "/executions", { chip_id: params.chipId, flow_name: params.flowName, status: params.status, skip: params.skip, limit: params.limit });
1517
1490
  case "execution": return client.getExecution(requireValue(params.executionId, "executionId"));
1518
- case "ai_reviews": return client.api.listTaskResultAiReviews({ chip_id: params.chipId, task_name: params.taskName, status: params.status, decision: params.decision, latest_only: params.latestOnly, skip: params.skip, limit: params.limit });
1519
- case "ai_review_runs": return client.api.listTaskResultAiReviewRuns({ chip_id: params.chipId, task_name: params.taskName, skip: params.skip, limit: params.limit });
1520
- case "ai_review_run": return client.api.getTaskResultAiReviewRun(requireValue(params.reviewRunId, "reviewRunId"));
1521
1491
  case "forum_posts": return client.listForumPosts({ status: params.status, chipId: params.chipId, limit: params.limit, skip: params.skip });
1522
1492
  case "provenance_stats": return client.getProvenanceStats();
1523
1493
  case "provenance_history": return client.api.getParameterHistory({ parameter_name: requireValue(params.parameterName ?? params.parameter, "parameterName"), qid: requireValue(params.qid, "qid"), limit: params.limit });
@@ -1940,15 +1910,6 @@ export default function qdashExtension(pi: ExtensionAPI) {
1940
1910
  parameters: Type.Object({ ...connectionParams, executionId: Type.String() }),
1941
1911
  });
1942
1912
 
1943
- registerQueryTool({
1944
- name: "qdash_list_ai_reviews",
1945
- label: "QDash List AI Reviews",
1946
- description: "List task-result AI reviews with optional filters.",
1947
- promptSnippet: "List QDash task-result AI reviews",
1948
- action: "ai_reviews",
1949
- parameters: Type.Object({ ...connectionParams, chipId: Type.Optional(Type.String()), taskName: Type.Optional(Type.String()), status: Type.Optional(Type.String()), decision: Type.Optional(Type.String()), latestOnly: Type.Optional(Type.Boolean()), limit: Type.Optional(Type.Number()), skip: Type.Optional(Type.Number()) }),
1950
- });
1951
-
1952
1913
  pi.registerTool({
1953
1914
  name: "qdash_create_agent_session",
1954
1915
  label: "QDash Create Agent Session",
@@ -2652,12 +2613,12 @@ export default function qdashExtension(pi: ExtensionAPI) {
2652
2613
  pi.registerTool({
2653
2614
  name: "qdash_build_qcal_evidence",
2654
2615
  label: "QDash Build QCal Evidence",
2655
- description: "Build a provider-neutral CalibrationEvidence bundle from a QDash task result for evaluation by pi-qcal.",
2656
- promptSnippet: "Convert QDash calibration task results into pi-qcal CalibrationEvidence",
2616
+ description: "Summarize a QDash task result (target, parameters, metrics, figure analysis) as evidence for pi-qcaleval's qcal_evaluate, returning the task figure as image content.",
2617
+ promptSnippet: "Summarize a QDash calibration task result as evidence for qcal_evaluate",
2657
2618
  promptGuidelines: [
2658
- "Use qdash_build_qcal_evidence before qcal_evaluate_bundle when the user asks to evaluate QDash calibration data with pi-qcal.",
2619
+ "Use qdash_build_qcal_evidence before qcal_evaluate when the user asks to evaluate a QDash calibration task with pi-qcaleval; pass the returned summary as the context of qcal_evaluate.",
2659
2620
  "qdash_build_qcal_evidence is read-only and only converts QDash data into a generic evidence bundle; it does not evaluate, execute, commit, or apply calibration parameters.",
2660
- "After qdash_build_qcal_evidence, pass details.evidence to qcal_evaluate_bundle and treat the result as advisory evidence.",
2621
+ "The task figure comes back as image content, so qcal_evaluate can follow directly without fetching the figure again; treat the evaluation as advisory evidence.",
2661
2622
  ],
2662
2623
  parameters: Type.Object({
2663
2624
  ...connectionParams,
@@ -2671,6 +2632,7 @@ export default function qdashExtension(pi: ExtensionAPI) {
2671
2632
  const client = await makeClient(params);
2672
2633
  const task = await client.getTaskResult(params.taskId) as unknown as Record<string, unknown>;
2673
2634
  const figures: Array<Record<string, unknown>> = [];
2635
+ const images: Array<{ type: "image"; data: string; mimeType: string }> = [];
2674
2636
  const notes: string[] = [];
2675
2637
  const figurePaths = Array.isArray(task.figure_path) ? task.figure_path.filter((item): item is string => typeof item === "string") : [];
2676
2638
  const jsonFigurePaths = Array.isArray(task.json_figure_path) ? task.json_figure_path.filter((item): item is string => typeof item === "string") : [];
@@ -2699,7 +2661,9 @@ export default function qdashExtension(pi: ExtensionAPI) {
2699
2661
  const bytes = Buffer.from(file.data);
2700
2662
  const mediaType = file.mediaType || mediaTypeForPath(file.path ?? figurePaths[index] ?? "");
2701
2663
  if (mediaType.startsWith("image/")) {
2702
- figures.push({ path: file.path ?? figurePaths[index], url: `data:${mediaType};base64,${bytes.toString("base64")}`, mimeType: mediaType, role: "plot" });
2664
+ const base64 = bytes.toString("base64");
2665
+ figures.push({ path: file.path ?? figurePaths[index], url: `data:${mediaType};base64,${base64}`, mimeType: mediaType, role: "plot" });
2666
+ images.push({ type: "image", data: base64, mimeType: mediaType });
2703
2667
  }
2704
2668
  } catch (error) {
2705
2669
  notes.push(`Figure image #${index + 1} embedding failed: ${error instanceof Error ? error.message : String(error)}`);
@@ -2744,7 +2708,8 @@ export default function qdashExtension(pi: ExtensionAPI) {
2744
2708
  },
2745
2709
  };
2746
2710
 
2747
- return toTextToolResult(qcalEvidenceText(evidence), { evidence }, { tool: "qdash_build_qcal_evidence", taskId: params.taskId, evidence });
2711
+ const result = toTextToolResult(qcalEvidenceText(evidence), { evidence }, { tool: "qdash_build_qcal_evidence", taskId: params.taskId, evidence });
2712
+ return { ...result, content: [...result.content, ...images] };
2748
2713
  },
2749
2714
  });
2750
2715
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oqtopus-team/pi-qdash",
3
- "version": "0.1.10-beta.15",
3
+ "version": "0.1.10",
4
4
  "description": "Pi extension for querying QDash via @oqtopus-team/qdash-client",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,7 +26,7 @@ Prefer the dedicated tool that matches the question. Use `qdash_query` only as a
26
26
  - `qdash_list_flows`, `qdash_get_flow` — list or inspect calibration flows
27
27
  - `qdash_get_pipeline_catalog`, `qdash_plan_pipeline` — compose and check a calibration pipeline spec before running it
28
28
  - `qdash_list_executions`, `qdash_get_execution`, `qdash_wait_execution`, `qdash_compare_executions` — inspect, await, or compare executions
29
- - `qdash_list_ai_reviews`, `qdash_get_provenance_stats` — inspect AI reviews or provenance status
29
+ - `qdash_get_provenance_stats` — inspect provenance status
30
30
  - `qdash_list_forum_posts`, `qdash_get_forum_post`, `qdash_list_forum_replies` — inspect Forum context
31
31
  - `qdash_preview_forum_evidence_reply`, `qdash_preview_forum_image_reply` — preview evidence or image replies without writing
32
32
  - `qdash_get_figure`, `qdash_get_task_figures`, `qdash_recent_calibration_figure`, `qdash_analyze_figure_json`, `qdash_build_qcal_evidence` — inspect or package figure evidence
@@ -164,5 +164,5 @@ When the user wants to preserve an investigated observation in QDash forum/notes
164
164
  - Use `qdash_compare_calibration` when the user asks what changed between recent calibration experiments; treat differences as evidence, not automatic approval to commit/apply parameters.
165
165
  - Use `qdash_recent_calibration_figure` when the user asks to see recent experiment images without a task ID.
166
166
  - Use `qdash_analyze_figure_json` for read-only numeric summaries of Plotly JSON calibration figures; keep domain-specific interpretation in the matching skill.
167
- - Use `qdash_build_qcal_evidence` when the user wants to evaluate a QDash calibration task with pi-qcal. It only converts QDash data into provider-neutral `CalibrationEvidence`; pass `details.evidence` to `qcal_evaluate_bundle` for the actual evaluation.
167
+ - Use `qdash_build_qcal_evidence` when the user wants to evaluate a QDash calibration task with pi-qcaleval. It only summarizes QDash data and returns the task figure; pass the summary as `context` to `qcal_evaluate` for the actual evaluation.
168
168
  - Prefer summarizing large responses with counts, IDs, time ranges, and notable values.