edgegate-mcp 0.1.1 → 0.2.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/README.md CHANGED
@@ -67,6 +67,7 @@ See [docs/tools.md](./docs/tools.md) for the full tool reference. Quick list:
67
67
  | `edgegate_get_report` | List recent runs |
68
68
  | `edgegate_get_audit_report` | Fetch the signed audit PDF |
69
69
  | `edgegate_setup_github_action` | Generate the GitHub Actions workflow + secret commands |
70
+ | `edgegate_compare_runs` | Diff two runs — gate flips, metric deltas, per-device breakdown, REGRESSION / IMPROVEMENT / NEUTRAL verdict |
70
71
 
71
72
  ## Skills
72
73
 
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { APIKeyCreateResponse, AuditReport, Pipeline, RunDetail, RunSummary, Workspace, WorkflowTemplate } from "./types.js";
1
+ import type { APIKeyCreateResponse, Pipeline, RunBundle, RunComparison, RunDetail, RunSummary, Workspace, WorkflowTemplate } from "./types.js";
2
2
  export interface EdgeGateClientOptions {
3
3
  apiUrl: string;
4
4
  apiKey: string;
@@ -27,28 +27,42 @@ export declare class EdgeGateClient {
27
27
  }): Promise<APIKeyCreateResponse>;
28
28
  createPipeline(workspaceId: string, body: {
29
29
  name: string;
30
- description?: string;
31
- models: Array<{
30
+ device_matrix: Array<{
32
31
  name: string;
33
- artifact_id: string;
32
+ enabled: boolean;
34
33
  }>;
35
- devices: string[];
34
+ promptpack_ref: {
35
+ promptpack_id: string;
36
+ version: string;
37
+ };
36
38
  gates: Array<{
37
39
  metric: string;
38
40
  operator: string;
39
41
  threshold: number;
42
+ description?: string;
43
+ }>;
44
+ run_policy?: {
45
+ warmup_runs?: number;
46
+ measurement_repeats?: number;
47
+ max_new_tokens?: number;
48
+ timeout_minutes?: number;
49
+ };
50
+ model_matrix?: Array<{
51
+ artifact_id: string;
52
+ label?: string;
40
53
  }>;
41
- promptpack_id?: string;
42
- repeats?: number;
43
54
  }): Promise<Pipeline>;
44
55
  listPipelines(workspaceId: string): Promise<Pipeline[]>;
45
- triggerRun(workspaceId: string, pipelineId: string, body?: {
56
+ triggerRun(workspaceId: string, body: {
57
+ pipeline_id: string;
46
58
  trigger?: string;
47
59
  model_artifact_id?: string;
48
60
  }): Promise<RunSummary>;
49
61
  getRun(workspaceId: string, runId: string): Promise<RunDetail>;
50
62
  listRuns(workspaceId: string, limit?: number): Promise<RunSummary[]>;
51
- getAuditReport(workspaceId: string, runId: string): Promise<AuditReport>;
63
+ listRunsByPipeline(workspaceId: string, pipelineId: string, limit?: number): Promise<RunSummary[]>;
64
+ getRunDiff(workspaceId: string, runId: string): Promise<RunComparison>;
65
+ getRunBundle(workspaceId: string, runId: string): Promise<RunBundle>;
52
66
  getWorkflowTemplate(workspaceId: string): Promise<WorkflowTemplate>;
53
67
  private request;
54
68
  }
package/dist/client.js CHANGED
@@ -39,8 +39,8 @@ export class EdgeGateClient {
39
39
  async listPipelines(workspaceId) {
40
40
  return this.request("GET", `/v1/workspaces/${workspaceId}/pipelines`);
41
41
  }
42
- async triggerRun(workspaceId, pipelineId, body = {}) {
43
- return this.request("POST", `/v1/workspaces/${workspaceId}/pipelines/${pipelineId}/runs`, body);
42
+ async triggerRun(workspaceId, body) {
43
+ return this.request("POST", `/v1/workspaces/${workspaceId}/runs`, body);
44
44
  }
45
45
  async getRun(workspaceId, runId) {
46
46
  return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}`);
@@ -48,8 +48,14 @@ export class EdgeGateClient {
48
48
  async listRuns(workspaceId, limit = 20) {
49
49
  return this.request("GET", `/v1/workspaces/${workspaceId}/runs?limit=${limit}`);
50
50
  }
51
- async getAuditReport(workspaceId, runId) {
52
- return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}/audit-report`);
51
+ async listRunsByPipeline(workspaceId, pipelineId, limit = 20) {
52
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs?pipeline_id=${pipelineId}&limit=${limit}`);
53
+ }
54
+ async getRunDiff(workspaceId, runId) {
55
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}/diff`);
56
+ }
57
+ async getRunBundle(workspaceId, runId) {
58
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}/bundle`);
53
59
  }
54
60
  async getWorkflowTemplate(workspaceId) {
55
61
  return this.request("GET", `/v1/workspaces/${workspaceId}/github-action/template`);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -11,6 +11,7 @@ import { checkStatusHandler, checkStatusInputSchema } from "./tools/check_status
11
11
  import { getReportHandler, getReportInputSchema } from "./tools/get_report.js";
12
12
  import { getAuditReportHandler, getAuditReportInputSchema } from "./tools/get_audit_report.js";
13
13
  import { setupGithubActionHandler, setupGithubActionInputSchema, } from "./tools/setup_github_action.js";
14
+ import { compareRunsHandler, compareRunsInputSchema, } from "./tools/compare_runs.js";
14
15
  const TOOLS = [
15
16
  {
16
17
  name: "edgegate_setup_workspace",
@@ -60,6 +61,15 @@ const TOOLS = [
60
61
  schema: setupGithubActionInputSchema,
61
62
  handler: setupGithubActionHandler,
62
63
  },
64
+ {
65
+ name: "edgegate_compare_runs",
66
+ description: "Diff two EdgeGate runs in the same pipeline — metrics delta, gate flips (✓→✗ regressions " +
67
+ "and ✗→✓ recoveries), per-device breakdown, and an overall verdict (REGRESSION / IMPROVEMENT / " +
68
+ "NEUTRAL / NO BASELINE). When baseline_run_id is omitted, auto-selects the most recent " +
69
+ "PASSED run from the same pipeline as the baseline.",
70
+ schema: compareRunsInputSchema,
71
+ handler: compareRunsHandler,
72
+ },
63
73
  ];
64
74
  function getClient() {
65
75
  const apiUrl = process.env.EDGEGATE_API_URL ?? "https://edgegateapi.frozo.ai";
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -23,25 +23,36 @@ function format(run) {
23
23
  const badge = run.status.toUpperCase();
24
24
  const lines = [
25
25
  `Run **${run.id}**: ${badge}`,
26
- `Pipeline: ${run.pipeline_id}`,
26
+ `Pipeline: ${run.pipeline_id} (${run.pipeline_name})`,
27
27
  `Trigger: ${run.trigger}`,
28
- `Started: ${run.started_at ?? "(pending)"}`,
28
+ `Started: ${run.created_at}`,
29
29
  `Completed: ${run.completed_at ?? "(in flight)"}`,
30
30
  ``,
31
31
  ];
32
- for (const cell of run.cells ?? []) {
33
- lines.push(`### Cell: ${cell.device_name}`);
34
- for (const [m, v] of Object.entries(cell.metrics)) {
35
- lines.push(`- ${m}: ${v}`);
32
+ if (run.normalized_metrics) {
33
+ lines.push(`### Metrics`);
34
+ for (const [metric, value] of Object.entries(run.normalized_metrics)) {
35
+ lines.push(`- ${metric}: ${value}`);
36
36
  }
37
- for (const gr of cell.gate_results ?? []) {
38
- const sym = gr.passed ? "✓" : "✗";
39
- lines.push(` ${sym} ${gr.metric} ${gr.passed ? "≤" : ">"} ${gr.threshold} (actual ${gr.actual})`);
37
+ lines.push(``);
38
+ }
39
+ if (run.gates_eval) {
40
+ lines.push(`### Gate Results`);
41
+ for (const gate of run.gates_eval.gates) {
42
+ const sym = gate.passed ? "✓" : "✗";
43
+ lines.push(` ${sym} ${gate.metric} ${gate.operator} ${gate.threshold} (actual ${gate.actual_value})`);
40
44
  }
45
+ lines.push(`Overall: ${run.gates_eval.passed ? "PASSED" : "FAILED"}`);
46
+ lines.push(``);
47
+ }
48
+ if (run.error_code) {
49
+ lines.push(`Error: ${run.error_code}`);
50
+ if (run.error_detail)
51
+ lines.push(`Detail: ${run.error_detail}`);
41
52
  lines.push(``);
42
53
  }
43
- if (run.evidence_bundle_url) {
44
- lines.push(`Evidence bundle: ${run.evidence_bundle_url}`);
54
+ if (run.bundle_artifact_id) {
55
+ lines.push(`Evidence bundle artifact: ${run.bundle_artifact_id}`, `Fetch bundle details with \`edgegate_get_audit_report\`.`);
45
56
  }
46
57
  return lines.join("\n");
47
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"check_status.js","sourceRoot":"","sources":["../../src/tools/check_status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAsB,EACtB,KAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;aACpF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,GAAc;IAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa;QACtB,SAAS,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE;QAC7B,aAAa,GAAG,CAAC,WAAW,EAAE;QAC9B,YAAY,GAAG,CAAC,OAAO,EAAE;QACzB,YAAY,GAAG,CAAC,UAAU,IAAI,WAAW,EAAE;QAC3C,cAAc,GAAG,CAAC,YAAY,IAAI,aAAa,EAAE;QACjD,EAAE;KACH,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,SAAS,YAAY,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QACrG,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"check_status.js","sourceRoot":"","sources":["../../src/tools/check_status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * edgegate_compare_runs — run-over-run diff with smart auto-baseline selection.
3
+ *
4
+ * When baseline_run_id is omitted:
5
+ * 1. Fetch candidate run's pipeline_id
6
+ * 2. List last 20 runs in that pipeline
7
+ * 3. Pick the most recent PASSED run with a bundle (excluding candidate itself)
8
+ * 4. Fallback: most recent completed run (any status) excluding candidate
9
+ * 5. If nothing found: "NO BASELINE" response
10
+ *
11
+ * The backend already exposes GET /v1/workspaces/{id}/runs/{run_id}/diff which
12
+ * returns the pre-computed, signed diff embedded in the evidence bundle (commit
13
+ * 41167a6). We call that endpoint for the candidate run — it internally uses
14
+ * the baseline the Celery task stored at completion time. When the user
15
+ * explicitly provides a baseline_run_id that differs from what the backend
16
+ * stored, we fall back to client-side diff from both runs' detail endpoints.
17
+ */
18
+ import { z } from "zod";
19
+ import { EdgeGateClient } from "../client.js";
20
+ import type { ToolResult } from "./setup_workspace.js";
21
+ export declare const compareRunsInputSchema: z.ZodObject<{
22
+ workspace_id: z.ZodString;
23
+ run_id: z.ZodString;
24
+ baseline_run_id: z.ZodOptional<z.ZodString>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ workspace_id: string;
27
+ run_id: string;
28
+ baseline_run_id?: string | undefined;
29
+ }, {
30
+ workspace_id: string;
31
+ run_id: string;
32
+ baseline_run_id?: string | undefined;
33
+ }>;
34
+ export type CompareRunsInput = z.infer<typeof compareRunsInputSchema>;
35
+ export declare function compareRunsHandler(client: EdgeGateClient, input: CompareRunsInput): Promise<ToolResult>;
@@ -0,0 +1,409 @@
1
+ /**
2
+ * edgegate_compare_runs — run-over-run diff with smart auto-baseline selection.
3
+ *
4
+ * When baseline_run_id is omitted:
5
+ * 1. Fetch candidate run's pipeline_id
6
+ * 2. List last 20 runs in that pipeline
7
+ * 3. Pick the most recent PASSED run with a bundle (excluding candidate itself)
8
+ * 4. Fallback: most recent completed run (any status) excluding candidate
9
+ * 5. If nothing found: "NO BASELINE" response
10
+ *
11
+ * The backend already exposes GET /v1/workspaces/{id}/runs/{run_id}/diff which
12
+ * returns the pre-computed, signed diff embedded in the evidence bundle (commit
13
+ * 41167a6). We call that endpoint for the candidate run — it internally uses
14
+ * the baseline the Celery task stored at completion time. When the user
15
+ * explicitly provides a baseline_run_id that differs from what the backend
16
+ * stored, we fall back to client-side diff from both runs' detail endpoints.
17
+ */
18
+ import { z } from "zod";
19
+ import { EdgeGateError } from "../client.js";
20
+ export const compareRunsInputSchema = z.object({
21
+ workspace_id: z.string().uuid(),
22
+ run_id: z.string().uuid().describe("Candidate run to evaluate"),
23
+ baseline_run_id: z
24
+ .string()
25
+ .uuid()
26
+ .optional()
27
+ .describe("Baseline to compare against. When omitted, auto-selects the most recent " +
28
+ "PASSED run from the same pipeline (excluding the candidate itself), " +
29
+ "or the most recent completed run as a fallback."),
30
+ });
31
+ // Metrics where lower is better (high delta% is bad)
32
+ const LOWER_IS_BETTER = new Set(["inference_time_ms", "peak_memory_mb", "latency_ms"]);
33
+ // Threshold for "significant regression" in lower-is-better metrics
34
+ const REGRESSION_THRESHOLD_PCT = 25;
35
+ export async function compareRunsHandler(client, input) {
36
+ try {
37
+ const { workspace_id, run_id, baseline_run_id } = input;
38
+ // --- Fetch candidate run detail (need pipeline_id for auto-baseline) ---
39
+ let candidateRun;
40
+ try {
41
+ candidateRun = await client.getRun(workspace_id, run_id);
42
+ }
43
+ catch (err) {
44
+ if (err instanceof EdgeGateError) {
45
+ return {
46
+ isError: true,
47
+ content: [
48
+ {
49
+ type: "text",
50
+ text: `Could not fetch candidate run ${run_id}: ${err.detail}`,
51
+ },
52
+ ],
53
+ };
54
+ }
55
+ throw err;
56
+ }
57
+ // --- Try the backend /diff endpoint first (Scenario A fast path) ---
58
+ // The backend stores the diff from the previous pipeline run at completion.
59
+ // If the caller did NOT supply a baseline_run_id (or it matches what the
60
+ // backend would pick), use the pre-computed signed diff directly.
61
+ if (!baseline_run_id) {
62
+ try {
63
+ const comparison = await client.getRunDiff(workspace_id, run_id);
64
+ // Backend returned a diff — render it
65
+ return { content: [{ type: "text", text: renderComparison(comparison, candidateRun) }] };
66
+ }
67
+ catch (diffErr) {
68
+ if (diffErr instanceof EdgeGateError && diffErr.status === 404) {
69
+ // No server-side diff yet: either first run or still in flight.
70
+ // Attempt client-side auto-baseline selection.
71
+ }
72
+ else {
73
+ // Unexpected error — propagate
74
+ if (diffErr instanceof EdgeGateError) {
75
+ return {
76
+ isError: true,
77
+ content: [
78
+ {
79
+ type: "text",
80
+ text: `EdgeGate returned ${diffErr.status} fetching diff: ${diffErr.detail}`,
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ throw diffErr;
86
+ }
87
+ }
88
+ }
89
+ // --- Auto-baseline or explicit baseline: client-side path ---
90
+ let resolvedBaselineId = baseline_run_id ?? null;
91
+ if (!resolvedBaselineId) {
92
+ // Auto-select: list recent runs in the same pipeline
93
+ resolvedBaselineId = await pickAutoBaseline(client, workspace_id, candidateRun);
94
+ if (!resolvedBaselineId) {
95
+ return {
96
+ content: [
97
+ {
98
+ type: "text",
99
+ text: formatNoBaseline(candidateRun),
100
+ },
101
+ ],
102
+ };
103
+ }
104
+ }
105
+ // Fetch baseline run detail
106
+ let baselineRun;
107
+ try {
108
+ baselineRun = await client.getRun(workspace_id, resolvedBaselineId);
109
+ }
110
+ catch (err) {
111
+ if (err instanceof EdgeGateError) {
112
+ return {
113
+ isError: true,
114
+ content: [
115
+ {
116
+ type: "text",
117
+ text: `Could not fetch baseline run ${resolvedBaselineId}: ${err.detail}`,
118
+ },
119
+ ],
120
+ };
121
+ }
122
+ throw err;
123
+ }
124
+ // Build client-side diff
125
+ const comparison = buildClientSideDiff(candidateRun, baselineRun);
126
+ return { content: [{ type: "text", text: renderComparison(comparison, candidateRun) }] };
127
+ }
128
+ catch (err) {
129
+ if (err instanceof EdgeGateError) {
130
+ return {
131
+ isError: true,
132
+ content: [{ type: "text", text: `EdgeGate returned ${err.status}: ${err.detail}` }],
133
+ };
134
+ }
135
+ throw err;
136
+ }
137
+ }
138
+ // ─── Auto-baseline selection ───────────────────────────────────────────────
139
+ async function pickAutoBaseline(client, workspaceId, candidateRun) {
140
+ const pipelineId = candidateRun.pipeline_id;
141
+ let runs;
142
+ try {
143
+ runs = await client.listRunsByPipeline(workspaceId, pipelineId, 20);
144
+ }
145
+ catch {
146
+ // Fall back to listing all runs if pipeline filter fails
147
+ try {
148
+ runs = await client.listRuns(workspaceId, 20);
149
+ }
150
+ catch {
151
+ return null;
152
+ }
153
+ }
154
+ // Filter to same pipeline, excluding candidate itself
155
+ const eligible = runs.filter((r) => r.id !== candidateRun.id && r.pipeline_id === pipelineId);
156
+ // Priority 1: most recent PASSED with a bundle
157
+ // (RunSummary doesn't have bundle_artifact_id, but passed status implies a bundle)
158
+ const passedRun = eligible.find((r) => r.status === "passed");
159
+ if (passedRun)
160
+ return passedRun.id;
161
+ // Priority 2: most recent completed run (any terminal status)
162
+ const completedRun = eligible.find((r) => ["passed", "failed", "error"].includes(r.status));
163
+ if (completedRun)
164
+ return completedRun.id;
165
+ return null;
166
+ }
167
+ // ─── Client-side diff construction ────────────────────────────────────────
168
+ function buildClientSideDiff(candidate, baseline) {
169
+ const candidateMetrics = candidate.normalized_metrics ?? {};
170
+ const baselineMetrics = baseline.normalized_metrics ?? {};
171
+ // Metric deltas
172
+ const allMetricKeys = new Set([
173
+ ...Object.keys(candidateMetrics),
174
+ ...Object.keys(baselineMetrics),
175
+ ]);
176
+ const metric_deltas = {};
177
+ for (const k of allMetricKeys) {
178
+ const cur = candidateMetrics[k] ?? null;
179
+ const prev = baselineMetrics[k] ?? null;
180
+ const delta = cur !== null && prev !== null ? cur - prev : null;
181
+ const delta_pct = delta !== null && prev !== null && prev !== 0 ? (delta / prev) * 100 : null;
182
+ metric_deltas[k] = { current: cur, previous: prev, delta, delta_pct };
183
+ }
184
+ // Gate flips
185
+ const candidateGates = candidate.gates_eval?.gates ?? [];
186
+ const baselineGates = baseline.gates_eval?.gates ?? [];
187
+ const prevByMetric = new Map(baselineGates.map((g) => [g.metric, g]));
188
+ const currByMetric = new Map(candidateGates.map((g) => [g.metric, g]));
189
+ const allGateMetrics = new Set([...prevByMetric.keys(), ...currByMetric.keys()]);
190
+ const gate_flips = [];
191
+ for (const m of [...allGateMetrics].sort()) {
192
+ const prev = prevByMetric.get(m) ?? null;
193
+ const curr = currByMetric.get(m) ?? null;
194
+ let transition;
195
+ if (!prev)
196
+ transition = "new";
197
+ else if (!curr)
198
+ transition = "removed";
199
+ else {
200
+ const p = prev.passed;
201
+ const c = curr.passed;
202
+ if (c && p)
203
+ transition = "unchanged";
204
+ else if (c && !p)
205
+ transition = "improved";
206
+ else if (!c && p)
207
+ transition = "regressed";
208
+ else
209
+ transition = "still_failing";
210
+ }
211
+ gate_flips.push({
212
+ metric: m,
213
+ transition,
214
+ previous: prev
215
+ ? {
216
+ passed: prev.passed,
217
+ threshold: prev.threshold,
218
+ operator: prev.operator,
219
+ actual_value: prev.actual_value,
220
+ }
221
+ : null,
222
+ current: curr
223
+ ? {
224
+ passed: curr.passed,
225
+ threshold: curr.threshold,
226
+ operator: curr.operator,
227
+ actual_value: curr.actual_value,
228
+ }
229
+ : null,
230
+ });
231
+ }
232
+ return {
233
+ current_run_id: candidate.id,
234
+ previous_run_id: baseline.id,
235
+ diff_sha256: null, // client-side, not signed
236
+ diff: {
237
+ current_run_id: candidate.id,
238
+ previous_run_id: baseline.id,
239
+ current_commit: {},
240
+ previous_commit: {},
241
+ current_completed_at: candidate.completed_at,
242
+ previous_completed_at: baseline.completed_at,
243
+ metric_deltas,
244
+ gate_flips,
245
+ per_device: null,
246
+ per_cell: null,
247
+ is_baseline: false,
248
+ },
249
+ created_at: new Date().toISOString(),
250
+ };
251
+ }
252
+ // ─── Rendering ─────────────────────────────────────────────────────────────
253
+ function renderComparison(comparison, candidateRun) {
254
+ const diff = comparison.diff;
255
+ const lines = [];
256
+ // Header
257
+ lines.push(`## Run Comparison`, ``, `**Pipeline:** ${candidateRun.pipeline_name} (${candidateRun.pipeline_id})`, `**Candidate:** \`${comparison.current_run_id}\` ` +
258
+ `(${diff.current_completed_at ?? "in flight"})`, `**Baseline:** \`${comparison.previous_run_id ?? "—"}\` ` +
259
+ `(${diff.previous_completed_at ?? "—"})`, ``);
260
+ if (diff.is_baseline) {
261
+ lines.push(`> **NO BASELINE** — this is the first completed run in this pipeline.`);
262
+ lines.push(``);
263
+ return lines.join("\n");
264
+ }
265
+ // Commit context (only if server-side diff has it)
266
+ const cc = diff.current_commit;
267
+ const pc = diff.previous_commit;
268
+ if (cc?.sha || pc?.sha) {
269
+ lines.push(`### Commit Context`);
270
+ if (cc?.sha)
271
+ lines.push(`**Candidate:** \`${cc.sha}\` — ${cc.message ?? ""}`);
272
+ if (pc?.sha)
273
+ lines.push(`**Baseline:** \`${pc.sha}\` — ${pc.message ?? ""}`);
274
+ lines.push(``);
275
+ }
276
+ // Metrics
277
+ const metricKeys = Object.keys(diff.metric_deltas).sort();
278
+ if (metricKeys.length > 0) {
279
+ lines.push(`### Metrics`);
280
+ lines.push(`| Metric | Baseline | Candidate | Delta | Direction |`);
281
+ lines.push(`|---|---|---|---|---|`);
282
+ for (const k of metricKeys) {
283
+ const m = diff.metric_deltas[k];
284
+ const pct = m.delta_pct !== null ? `${m.delta_pct > 0 ? "+" : ""}${m.delta_pct.toFixed(1)}%` : "—";
285
+ const arrow = m.delta === null ? "" : m.delta > 0 ? "↑" : m.delta < 0 ? "↓" : "→";
286
+ const direction = m.delta === null ? "—" : buildDirectionLabel(k, m.delta);
287
+ lines.push(`| ${k} | ${fmt(m.previous)} | ${fmt(m.current)} | ${fmtDelta(m.delta)} (${pct}) ${arrow} | ${direction} |`);
288
+ }
289
+ lines.push(``);
290
+ }
291
+ // Gate flips
292
+ if (diff.gate_flips.length > 0) {
293
+ lines.push(`### Gate Status`);
294
+ lines.push(`| Gate | Baseline | Candidate | Status |`);
295
+ lines.push(`|---|---|---|---|`);
296
+ for (const gf of diff.gate_flips) {
297
+ const baseIcon = gateIcon(gf.previous?.passed ?? null);
298
+ const candIcon = gateIcon(gf.current?.passed ?? null);
299
+ const statusLabel = flipLabel(gf.transition);
300
+ lines.push(`| ${gf.metric} | ${baseIcon} | ${candIcon} | ${statusLabel} |`);
301
+ }
302
+ lines.push(``);
303
+ }
304
+ // Per-device breakdown
305
+ if (diff.per_device && Object.keys(diff.per_device).length > 0) {
306
+ lines.push(`### Per-Device Breakdown`);
307
+ for (const [device, metrics] of Object.entries(diff.per_device)) {
308
+ lines.push(`**${device}**`);
309
+ for (const [k, m] of Object.entries(metrics)) {
310
+ const pct = m.delta_pct !== null ? `${m.delta_pct > 0 ? "+" : ""}${m.delta_pct.toFixed(1)}%` : "—";
311
+ lines.push(` - ${k}: ${fmt(m.previous)} → ${fmt(m.current)} (${pct})`);
312
+ }
313
+ }
314
+ lines.push(``);
315
+ }
316
+ // Verdict
317
+ const verdict = computeVerdict(diff.gate_flips, diff.metric_deltas);
318
+ lines.push(`### Verdict`);
319
+ lines.push(``);
320
+ lines.push(verdictBadge(verdict));
321
+ lines.push(``);
322
+ // Audit trail
323
+ lines.push(`### Audit Trail`);
324
+ if (comparison.diff_sha256) {
325
+ lines.push(`Diff SHA-256: \`${comparison.diff_sha256}\` (signed, embedded in evidence bundle)`);
326
+ }
327
+ else {
328
+ lines.push(`Diff computed client-side (no SHA-256 — backend diff not yet available for this run)`);
329
+ }
330
+ if (candidateRun.bundle_artifact_id) {
331
+ lines.push(`Candidate bundle artifact: \`${candidateRun.bundle_artifact_id}\``);
332
+ }
333
+ if (comparison.previous_run_id) {
334
+ lines.push(`Baseline run ID: \`${comparison.previous_run_id}\``);
335
+ }
336
+ return lines.join("\n");
337
+ }
338
+ function formatNoBaseline(candidateRun) {
339
+ return [
340
+ `## Run Comparison`,
341
+ ``,
342
+ `**Pipeline:** ${candidateRun.pipeline_name} (${candidateRun.pipeline_id})`,
343
+ `**Candidate:** \`${candidateRun.id}\``,
344
+ ``,
345
+ `> **NO BASELINE** — this is the first completed run in pipeline "${candidateRun.pipeline_name}", ` +
346
+ `or no prior completed runs were found. There is nothing to compare against yet.`,
347
+ ``,
348
+ `**Verdict: NO BASELINE**`,
349
+ ].join("\n");
350
+ }
351
+ // ─── Helpers ───────────────────────────────────────────────────────────────
352
+ function fmt(v) {
353
+ return v === null ? "—" : v.toFixed(2);
354
+ }
355
+ function fmtDelta(v) {
356
+ if (v === null)
357
+ return "—";
358
+ return `${v > 0 ? "+" : ""}${v.toFixed(2)}`;
359
+ }
360
+ function gateIcon(passed) {
361
+ if (passed === null)
362
+ return "—";
363
+ return passed ? "✓" : "✗";
364
+ }
365
+ function flipLabel(transition) {
366
+ switch (transition) {
367
+ case "regressed": return "**REGRESSION** ✓→✗";
368
+ case "improved": return "RECOVERY ✗→✓";
369
+ case "unchanged": return "passing";
370
+ case "still_failing": return "still failing";
371
+ case "new": return "new gate";
372
+ case "removed": return "removed";
373
+ default: return transition;
374
+ }
375
+ }
376
+ function buildDirectionLabel(metric, delta) {
377
+ if (delta === 0)
378
+ return "no change";
379
+ const lowerBetter = LOWER_IS_BETTER.has(metric);
380
+ if (lowerBetter) {
381
+ return delta > 0 ? "worse ↑" : "better ↓";
382
+ }
383
+ return delta > 0 ? "better ↑" : "worse ↓";
384
+ }
385
+ function computeVerdict(gateFlips, metricDeltas) {
386
+ const hasRegression = gateFlips.some((gf) => gf.transition === "regressed");
387
+ const hasRecovery = gateFlips.some((gf) => gf.transition === "improved");
388
+ // Also flag metric-only regression even if no gate flip
389
+ const significantMetricRegression = Object.entries(metricDeltas).some(([k, m]) => {
390
+ if (!LOWER_IS_BETTER.has(k))
391
+ return false;
392
+ return m.delta_pct !== null && m.delta_pct >= REGRESSION_THRESHOLD_PCT;
393
+ });
394
+ if (hasRegression || significantMetricRegression)
395
+ return "REGRESSION";
396
+ if (hasRecovery && !hasRegression)
397
+ return "IMPROVEMENT";
398
+ return "NEUTRAL";
399
+ }
400
+ function verdictBadge(verdict) {
401
+ switch (verdict) {
402
+ case "REGRESSION": return `**REGRESSION** — one or more gates regressed or a lower-is-better metric increased by ≥${REGRESSION_THRESHOLD_PCT}%.`;
403
+ case "IMPROVEMENT": return `**IMPROVEMENT** — previously-failing gates now pass; no regressions.`;
404
+ case "NEUTRAL": return `**NEUTRAL** — no gate flips and no significant metric regressions.`;
405
+ case "NO BASELINE": return `**NO BASELINE** — no prior run to compare against.`;
406
+ default: return `**${verdict}**`;
407
+ }
408
+ }
409
+ //# sourceMappingURL=compare_runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare_runs.js","sourceRoot":"","sources":["../../src/tools/compare_runs.ts"],"names":[],"mappings":"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"}
@@ -4,64 +4,77 @@ import type { ToolResult } from "./setup_workspace.js";
4
4
  export declare const createPipelineInputSchema: z.ZodObject<{
5
5
  workspace_id: z.ZodString;
6
6
  name: z.ZodString;
7
- description: z.ZodOptional<z.ZodString>;
8
- models: z.ZodArray<z.ZodObject<{
9
- name: z.ZodString;
10
- artifact_id: z.ZodString;
11
- }, "strip", z.ZodTypeAny, {
12
- name: string;
13
- artifact_id: string;
14
- }, {
15
- name: string;
16
- artifact_id: string;
17
- }>, "many">;
7
+ /** Required. Use the string promptpack_id (e.g. "image-classification-bench-v1"), not the UUID row id. */
8
+ promptpack_id: z.ZodString;
9
+ /** PromptPack version string, e.g. "1.0.0" */
10
+ promptpack_version: z.ZodDefault<z.ZodString>;
11
+ /** Device names to include. E.g. ["Samsung Galaxy S24 (Family)"] */
18
12
  devices: z.ZodArray<z.ZodString, "many">;
19
13
  gates: z.ZodArray<z.ZodObject<{
20
14
  metric: z.ZodEnum<["inference_time_ms", "peak_memory_mb", "throughput_tps"]>;
21
15
  operator: z.ZodEnum<["<=", "<", ">=", ">", "=="]>;
22
16
  threshold: z.ZodNumber;
17
+ description: z.ZodOptional<z.ZodString>;
23
18
  }, "strip", z.ZodTypeAny, {
24
19
  metric: "inference_time_ms" | "peak_memory_mb" | "throughput_tps";
25
20
  operator: "<=" | "<" | ">=" | ">" | "==";
26
21
  threshold: number;
22
+ description?: string | undefined;
27
23
  }, {
28
24
  metric: "inference_time_ms" | "peak_memory_mb" | "throughput_tps";
29
25
  operator: "<=" | "<" | ">=" | ">" | "==";
30
26
  threshold: number;
27
+ description?: string | undefined;
31
28
  }>, "many">;
32
- promptpack_id: z.ZodOptional<z.ZodString>;
29
+ /**
30
+ * Optional multi-model matrix. When omitted the pipeline runs in legacy
31
+ * single-model mode (model_artifact_id is supplied per-run instead).
32
+ */
33
+ models: z.ZodOptional<z.ZodArray<z.ZodObject<{
34
+ name: z.ZodString;
35
+ artifact_id: z.ZodString;
36
+ }, "strip", z.ZodTypeAny, {
37
+ name: string;
38
+ artifact_id: string;
39
+ }, {
40
+ name: string;
41
+ artifact_id: string;
42
+ }>, "many">>;
43
+ /** Measurement repeats per cell (1–5). Defaults to API default (3). */
33
44
  repeats: z.ZodOptional<z.ZodNumber>;
34
45
  }, "strip", z.ZodTypeAny, {
35
46
  workspace_id: string;
36
47
  name: string;
37
- models: {
38
- name: string;
39
- artifact_id: string;
40
- }[];
48
+ promptpack_id: string;
49
+ promptpack_version: string;
41
50
  devices: string[];
42
51
  gates: {
43
52
  metric: "inference_time_ms" | "peak_memory_mb" | "throughput_tps";
44
53
  operator: "<=" | "<" | ">=" | ">" | "==";
45
54
  threshold: number;
55
+ description?: string | undefined;
46
56
  }[];
47
- description?: string | undefined;
48
- promptpack_id?: string | undefined;
57
+ models?: {
58
+ name: string;
59
+ artifact_id: string;
60
+ }[] | undefined;
49
61
  repeats?: number | undefined;
50
62
  }, {
51
63
  workspace_id: string;
52
64
  name: string;
53
- models: {
54
- name: string;
55
- artifact_id: string;
56
- }[];
65
+ promptpack_id: string;
57
66
  devices: string[];
58
67
  gates: {
59
68
  metric: "inference_time_ms" | "peak_memory_mb" | "throughput_tps";
60
69
  operator: "<=" | "<" | ">=" | ">" | "==";
61
70
  threshold: number;
71
+ description?: string | undefined;
62
72
  }[];
63
- description?: string | undefined;
64
- promptpack_id?: string | undefined;
73
+ promptpack_version?: string | undefined;
74
+ models?: {
75
+ name: string;
76
+ artifact_id: string;
77
+ }[] | undefined;
65
78
  repeats?: number | undefined;
66
79
  }>;
67
80
  export type CreatePipelineInput = z.infer<typeof createPipelineInputSchema>;
@@ -1,28 +1,48 @@
1
1
  import { z } from "zod";
2
2
  import { EdgeGateError } from "../client.js";
3
3
  const MAX_CELLS = 25;
4
+ // Operator mapping: user-friendly symbols → API enum values
5
+ const OPERATOR_MAP = {
6
+ "<=": "lte",
7
+ "<": "lt",
8
+ ">=": "gte",
9
+ ">": "gt",
10
+ "==": "eq",
11
+ };
4
12
  export const createPipelineInputSchema = z.object({
5
13
  workspace_id: z.string().uuid(),
6
14
  name: z.string().min(1).max(255),
7
- description: z.string().optional(),
8
- models: z
9
- .array(z.object({ name: z.string().min(1), artifact_id: z.string().min(1) }))
10
- .min(1)
11
- .max(10),
15
+ /** Required. Use the string promptpack_id (e.g. "image-classification-bench-v1"), not the UUID row id. */
16
+ promptpack_id: z.string().min(1),
17
+ /** PromptPack version string, e.g. "1.0.0" */
18
+ promptpack_version: z.string().min(1).default("1.0.0"),
19
+ /** Device names to include. E.g. ["Samsung Galaxy S24 (Family)"] */
12
20
  devices: z.array(z.string().min(1)).min(1).max(5),
13
21
  gates: z
14
22
  .array(z.object({
15
23
  metric: z.enum(["inference_time_ms", "peak_memory_mb", "throughput_tps"]),
16
24
  operator: z.enum(["<=", "<", ">=", ">", "=="]),
17
25
  threshold: z.number().positive(),
26
+ description: z.string().optional(),
18
27
  }))
19
28
  .min(1),
20
- promptpack_id: z.string().uuid().optional(),
29
+ /**
30
+ * Optional multi-model matrix. When omitted the pipeline runs in legacy
31
+ * single-model mode (model_artifact_id is supplied per-run instead).
32
+ */
33
+ models: z
34
+ .array(z.object({ name: z.string().min(1), artifact_id: z.string().min(1) }))
35
+ .min(1)
36
+ .max(10)
37
+ .optional(),
38
+ /** Measurement repeats per cell (1–5). Defaults to API default (3). */
21
39
  repeats: z.number().int().min(1).max(5).optional(),
22
40
  });
23
41
  export async function createPipelineHandler(client, input) {
24
- const cellCount = input.models.length * input.devices.length;
25
- if (cellCount > MAX_CELLS) {
42
+ // Guard: cell count limit applies when model_matrix is provided
43
+ const modelCount = input.models?.length ?? 1;
44
+ const cellCount = modelCount * input.devices.length;
45
+ if (input.models && cellCount > MAX_CELLS) {
26
46
  return {
27
47
  isError: true,
28
48
  content: [
@@ -35,15 +55,28 @@ export async function createPipelineHandler(client, input) {
35
55
  ],
36
56
  };
37
57
  }
58
+ // Translate user-facing shape → API shape
59
+ const device_matrix = input.devices.map((name) => ({ name, enabled: true }));
60
+ const promptpack_ref = {
61
+ promptpack_id: input.promptpack_id,
62
+ version: input.promptpack_version,
63
+ };
64
+ const gates = input.gates.map((g) => ({
65
+ metric: g.metric,
66
+ operator: OPERATOR_MAP[g.operator] ?? g.operator,
67
+ threshold: g.threshold,
68
+ ...(g.description !== undefined ? { description: g.description } : {}),
69
+ }));
70
+ const model_matrix = input.models?.map((m) => ({ artifact_id: m.artifact_id, label: m.name }));
71
+ const run_policy = input.repeats !== undefined ? { measurement_repeats: input.repeats } : undefined;
38
72
  try {
39
73
  const pipeline = await client.createPipeline(input.workspace_id, {
40
74
  name: input.name,
41
- description: input.description,
42
- models: input.models,
43
- devices: input.devices,
44
- gates: input.gates,
45
- promptpack_id: input.promptpack_id,
46
- repeats: input.repeats,
75
+ device_matrix,
76
+ promptpack_ref,
77
+ gates,
78
+ ...(model_matrix !== undefined ? { model_matrix } : {}),
79
+ ...(run_policy !== undefined ? { run_policy } : {}),
47
80
  });
48
81
  return {
49
82
  content: [
@@ -52,8 +85,9 @@ export async function createPipelineHandler(client, input) {
52
85
  text: [
53
86
  `Created pipeline **${pipeline.name}** (id=${pipeline.id}).`,
54
87
  ``,
55
- `- ${input.models.length} model(s) × ${input.devices.length} device(s) = ${cellCount} cell(s) per run`,
56
- `- ${input.gates.length} gate(s)`,
88
+ `- ${pipeline.device_count} device(s) × ${Math.max(pipeline.model_count, 1)} model(s) = ${pipeline.cell_count} cell(s) per run`,
89
+ `- ${pipeline.gate_count} gate(s)`,
90
+ `- PromptPack: ${pipeline.promptpack_id}@${pipeline.promptpack_version}`,
57
91
  ``,
58
92
  `Trigger a run with \`edgegate_run_gate\`, or wire CI with \`edgegate_setup_github_action\`.`,
59
93
  ].join("\n"),
@@ -1 +1 @@
1
- {"version":3,"file":"create_pipeline.js","sourceRoot":"","sources":["../../src/tools/create_pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create_pipeline.js","sourceRoot":"","sources":["../../src/tools/create_pipeline.ts"],"names":[],"mappings":"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"}
@@ -6,23 +6,35 @@ export const getAuditReportInputSchema = z.object({
6
6
  });
7
7
  export async function getAuditReportHandler(client, input) {
8
8
  try {
9
- const report = await client.getAuditReport(input.workspace_id, input.run_id);
9
+ const bundle = await client.getRunBundle(input.workspace_id, input.run_id);
10
+ const lines = [
11
+ `Evidence bundle for run ${input.run_id}:`,
12
+ ``,
13
+ `Status: ${bundle.status.toUpperCase()}`,
14
+ `Pipeline: ${bundle.pipeline_id} (${bundle.pipeline_name})`,
15
+ `Bundle artifact ID: ${bundle.bundle_artifact_id ?? "(not yet generated)"}`,
16
+ ``,
17
+ ];
18
+ if (bundle.normalized_metrics) {
19
+ lines.push(`### Metrics`);
20
+ for (const [metric, value] of Object.entries(bundle.normalized_metrics)) {
21
+ lines.push(`- ${metric}: ${value}`);
22
+ }
23
+ lines.push(``);
24
+ }
25
+ if (bundle.gates_eval) {
26
+ lines.push(`### Gate Decisions`);
27
+ for (const gate of bundle.gates_eval.gates) {
28
+ const sym = gate.passed ? "✓" : "✗";
29
+ lines.push(` ${sym} ${gate.metric} ${gate.operator} ${gate.threshold} (actual ${gate.actual_value})`);
30
+ }
31
+ lines.push(`Overall: ${bundle.gates_eval.passed ? "PASSED" : "FAILED"}`);
32
+ lines.push(``);
33
+ }
34
+ lines.push(`The bundle artifact ID can be used with the EdgeGate API to download the ` +
35
+ `signed evidence bundle containing the full SHA-256 manifest and device fingerprints.`);
10
36
  return {
11
- content: [
12
- {
13
- type: "text",
14
- text: [
15
- `Audit report for run ${input.run_id}:`,
16
- ``,
17
- `Download URL: ${report.url}`,
18
- `Generated: ${report.generated_at}`,
19
- ``,
20
- `The URL is signed and time-limited (typically 1h). The PDF contains ` +
21
- `the signed evidence bundle hash, device fingerprints, and gate decisions — ` +
22
- `keep it with your compliance records.`,
23
- ].join("\n"),
24
- },
25
- ],
37
+ content: [{ type: "text", text: lines.join("\n") }],
26
38
  };
27
39
  }
28
40
  catch (err) {
@@ -32,10 +44,13 @@ export async function getAuditReportHandler(client, input) {
32
44
  content: [
33
45
  {
34
46
  type: "text",
35
- text: err.status === 404
36
- ? `No audit report for run ${input.run_id} yet. Reports are generated ` +
37
- `asynchronously after the run completes try again in 1-2 minutes.`
38
- : `EdgeGate returned ${err.status}: ${err.detail}`,
47
+ text: err.status === 409
48
+ ? `Evidence bundle not available yet the run has not completed. ` +
49
+ `Check status with \`edgegate_check_status\` and retry when it is PASSED or FAILED.`
50
+ : err.status === 404
51
+ ? `No evidence bundle for run ${input.run_id} yet. ` +
52
+ `Bundles are generated after the run completes — try again in 1-2 minutes.`
53
+ : `EdgeGate returned ${err.status}: ${err.detail}`,
39
54
  },
40
55
  ],
41
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"get_audit_report.js","sourceRoot":"","sources":["../../src/tools/get_audit_report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAsB,EACtB,KAA0B;IAE1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,wBAAwB,KAAK,CAAC,MAAM,GAAG;wBACvC,EAAE;wBACF,iBAAiB,MAAM,CAAC,GAAG,EAAE;wBAC7B,cAAc,MAAM,CAAC,YAAY,EAAE;wBACnC,EAAE;wBACF,sEAAsE;4BACpE,6EAA6E;4BAC7E,uCAAuC;qBAC1C,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EACF,GAAG,CAAC,MAAM,KAAK,GAAG;4BAChB,CAAC,CAAC,2BAA2B,KAAK,CAAC,MAAM,8BAA8B;gCACrE,oEAAoE;4BACtE,CAAC,CAAC,qBAAqB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE;qBACvD;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"get_audit_report.js","sourceRoot":"","sources":["../../src/tools/get_audit_report.ts"],"names":[],"mappings":"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"}
@@ -19,10 +19,10 @@ export async function getReportHandler(client, input) {
19
19
  }
20
20
  const rows = runs
21
21
  .map((r) => {
22
- const dur = r.started_at && r.completed_at
23
- ? `${Math.round((new Date(r.completed_at).getTime() - new Date(r.started_at).getTime()) / 1000)}s`
22
+ const dur = r.created_at && r.completed_at
23
+ ? `${Math.round((new Date(r.completed_at).getTime() - new Date(r.created_at).getTime()) / 1000)}s`
24
24
  : "-";
25
- return `| ${r.id} | ${r.status} | ${r.trigger} | ${dur} | ${r.started_at ?? "-"} |`;
25
+ return `| ${r.id} | ${r.status} | ${r.trigger} | ${dur} | ${r.created_at ?? "-"} |`;
26
26
  })
27
27
  .join("\n");
28
28
  return {
@@ -7,9 +7,12 @@ export const runGateInputSchema = z.object({
7
7
  });
8
8
  export async function runGateHandler(client, input) {
9
9
  try {
10
- const run = await client.triggerRun(input.workspace_id, input.pipeline_id, {
11
- trigger: "mcp",
12
- model_artifact_id: input.model_artifact_id,
10
+ const run = await client.triggerRun(input.workspace_id, {
11
+ pipeline_id: input.pipeline_id,
12
+ trigger: "manual",
13
+ ...(input.model_artifact_id !== undefined
14
+ ? { model_artifact_id: input.model_artifact_id }
15
+ : {}),
13
16
  });
14
17
  return {
15
18
  content: [
@@ -1 +1 @@
1
- {"version":3,"file":"run_gate.js","sourceRoot":"","sources":["../../src/tools/run_gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC9B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAsB,EACtB,KAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE;YACzE,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;SAC3C,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,mBAAmB,GAAG,CAAC,EAAE,kBAAkB,KAAK,CAAC,WAAW,GAAG;wBAC/D,EAAE;wBACF,mBAAmB;wBACnB,8CAA8C,KAAK,CAAC,YAAY,eAAe,GAAG,CAAC,EAAE,QAAQ;wBAC7F,EAAE;wBACF,kDAAkD;qBACnD,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EACF,GAAG,CAAC,MAAM,KAAK,GAAG;4BAChB,CAAC,CAAC,gEAAgE;gCAChE,6DAA6D;4BAC/D,CAAC,CAAC,0BAA0B,GAAG,CAAC,MAAM,EAAE;qBAC7C;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"run_gate.js","sourceRoot":"","sources":["../../src/tools/run_gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC9B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAsB,EACtB,KAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,EAAE;YACtD,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,QAAQ;YACjB,GAAG,CAAC,KAAK,CAAC,iBAAiB,KAAK,SAAS;gBACvC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE;gBAChD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,mBAAmB,GAAG,CAAC,EAAE,kBAAkB,KAAK,CAAC,WAAW,GAAG;wBAC/D,EAAE;wBACF,mBAAmB;wBACnB,8CAA8C,KAAK,CAAC,YAAY,eAAe,GAAG,CAAC,EAAE,QAAQ;wBAC7F,EAAE;wBACF,kDAAkD;qBACnD,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EACF,GAAG,CAAC,MAAM,KAAK,GAAG;4BAChB,CAAC,CAAC,gEAAgE;gCAChE,6DAA6D;4BAC/D,CAAC,CAAC,0BAA0B,GAAG,CAAC,MAAM,EAAE;qBAC7C;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
package/dist/types.d.ts CHANGED
@@ -10,12 +10,20 @@ export interface Workspace {
10
10
  }
11
11
  export interface Pipeline {
12
12
  id: UUID;
13
- workspace_id: UUID;
14
13
  name: string;
15
- description: string | null;
16
- status: "active" | "paused";
17
- pipeline_yaml: string;
14
+ device_count: number;
15
+ model_count: number;
16
+ gate_count: number;
17
+ cell_count: number;
18
+ promptpack_id: string;
19
+ promptpack_version: string;
18
20
  created_at: string;
21
+ updated_at: string;
22
+ last_run: {
23
+ id: UUID;
24
+ status: string;
25
+ created_at: string;
26
+ } | null;
19
27
  }
20
28
  export interface Gate {
21
29
  metric: string;
@@ -24,27 +32,45 @@ export interface Gate {
24
32
  }
25
33
  export interface RunSummary {
26
34
  id: UUID;
27
- workspace_id: UUID;
28
35
  pipeline_id: UUID;
36
+ pipeline_name: string;
29
37
  status: "pending" | "running" | "passed" | "failed" | "error";
30
- started_at: string | null;
31
- completed_at: string | null;
32
38
  trigger: string;
39
+ model_artifact_id: UUID | null;
40
+ model_filename: string | null;
41
+ error_code: string | null;
42
+ error_detail: string | null;
43
+ created_at: string;
44
+ updated_at: string;
45
+ completed_at: string | null;
46
+ hub_model_id: string | null;
47
+ hub_job_id: string | null;
48
+ }
49
+ export interface GateEvalResult {
50
+ metric: string;
51
+ passed: boolean;
52
+ operator: string;
53
+ threshold: number;
54
+ description: string | null;
55
+ actual_value: number;
33
56
  }
34
- export interface RunCell {
35
- model_artifact_id: UUID;
36
- device_name: string;
37
- metrics: Record<string, number>;
38
- gate_results: Array<{
39
- metric: string;
40
- passed: boolean;
41
- threshold: number;
42
- actual: number;
43
- }>;
57
+ export interface GatesEval {
58
+ gates: GateEvalResult[];
59
+ passed: boolean;
44
60
  }
45
61
  export interface RunDetail extends RunSummary {
46
- cells: RunCell[];
47
- evidence_bundle_url: string | null;
62
+ normalized_metrics: Record<string, number> | null;
63
+ gates_eval: GatesEval | null;
64
+ bundle_artifact_id: UUID | null;
65
+ }
66
+ export interface RunBundle {
67
+ run_id: UUID;
68
+ status: string;
69
+ pipeline_id: UUID;
70
+ pipeline_name: string;
71
+ normalized_metrics: Record<string, number> | null;
72
+ gates_eval: GatesEval | null;
73
+ bundle_artifact_id: UUID | null;
48
74
  }
49
75
  export interface APIKeyCreateResponse {
50
76
  id: UUID;
@@ -58,7 +84,51 @@ export interface WorkflowTemplate {
58
84
  api_url: string;
59
85
  secret_names: string[];
60
86
  }
87
+ /** @deprecated Not used — audit-report endpoint does not exist; use RunBundle instead. */
61
88
  export interface AuditReport {
62
- url: string;
63
- generated_at: string;
89
+ url?: string;
90
+ generated_at?: string;
91
+ }
92
+ export interface MetricDelta {
93
+ current: number | null;
94
+ previous: number | null;
95
+ delta: number | null;
96
+ delta_pct: number | null;
97
+ }
98
+ export interface GateFlip {
99
+ metric: string;
100
+ /** "unchanged" | "improved" | "regressed" | "still_failing" | "new" | "removed" */
101
+ transition: string;
102
+ previous: {
103
+ passed: boolean | null;
104
+ threshold: number | null;
105
+ operator: string | null;
106
+ actual_value: number | null;
107
+ } | null;
108
+ current: {
109
+ passed: boolean | null;
110
+ threshold: number | null;
111
+ operator: string | null;
112
+ actual_value: number | null;
113
+ } | null;
114
+ }
115
+ export interface RunDiffPayload {
116
+ current_run_id: UUID;
117
+ previous_run_id: UUID | null;
118
+ current_commit: Record<string, string | null>;
119
+ previous_commit: Record<string, string | null> | null;
120
+ current_completed_at: string | null;
121
+ previous_completed_at: string | null;
122
+ metric_deltas: Record<string, MetricDelta>;
123
+ gate_flips: GateFlip[];
124
+ per_device: Record<string, Record<string, MetricDelta>> | null;
125
+ per_cell: unknown[] | null;
126
+ is_baseline: boolean;
127
+ }
128
+ export interface RunComparison {
129
+ current_run_id: UUID;
130
+ previous_run_id: UUID | null;
131
+ diff_sha256: string | null;
132
+ diff: RunDiffPayload;
133
+ created_at: string;
64
134
  }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.1";
2
- export declare const USER_AGENT = "edgegate-mcp/0.1.1";
1
+ export declare const VERSION = "0.2.0";
2
+ export declare const USER_AGENT = "edgegate-mcp/0.2.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
- export const VERSION = "0.1.1";
1
+ export const VERSION = "0.2.0";
2
2
  export const USER_AGENT = `edgegate-mcp/${VERSION}`;
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edgegate-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for EdgeGate — set up edge-AI regression gates from Claude Code, Cursor, or Claude Desktop.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,3 +12,7 @@ The user wants to know how a run is doing.
12
12
  3. Render the result. If the run is FAILED, lead with the violating gate and the actual value — don't bury it.
13
13
 
14
14
  For PASSED runs, briefly summarize the metrics so the user has the numbers handy for a PR comment.
15
+
16
+ ## "Is this run a regression?"
17
+
18
+ If the user asks whether a run is a regression, or wants to see how it compares to the previous one, call `edgegate_compare_runs` with the `run_id` (and optionally a `baseline_run_id`). The tool auto-selects the baseline from the same pipeline when no explicit baseline is given. Read the **Verdict** section of the output — REGRESSION means at least one gate flipped ✓→✗ or a lower-is-better metric increased by ≥ 25%.