@inferevents/mcp 0.5.3 → 1.0.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/api-client.d.ts +141 -59
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +59 -69
- package/dist/api-client.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +90 -186
- package/dist/server.js.map +1 -1
- package/dist/tool-result.d.ts +34 -0
- package/dist/tool-result.d.ts.map +1 -0
- package/dist/tool-result.js +30 -0
- package/dist/tool-result.js.map +1 -0
- package/dist/tools/annotate-span.d.ts +7 -0
- package/dist/tools/annotate-span.d.ts.map +1 -0
- package/dist/tools/annotate-span.js +16 -0
- package/dist/tools/annotate-span.js.map +1 -0
- package/dist/tools/annotate-trace.d.ts +7 -0
- package/dist/tools/annotate-trace.d.ts.map +1 -0
- package/dist/tools/annotate-trace.js +16 -0
- package/dist/tools/annotate-trace.js.map +1 -0
- package/dist/tools/create-project.d.ts.map +1 -1
- package/dist/tools/create-project.js +39 -7
- package/dist/tools/create-project.js.map +1 -1
- package/dist/tools/deprecated-tools.d.ts +16 -0
- package/dist/tools/deprecated-tools.d.ts.map +1 -0
- package/dist/tools/deprecated-tools.js +78 -0
- package/dist/tools/deprecated-tools.js.map +1 -0
- package/dist/tools/deprecated.d.ts +25 -0
- package/dist/tools/deprecated.d.ts.map +1 -0
- package/dist/tools/deprecated.js +42 -0
- package/dist/tools/deprecated.js.map +1 -0
- package/dist/tools/get-cost-stats.d.ts +18 -0
- package/dist/tools/get-cost-stats.d.ts.map +1 -0
- package/dist/tools/get-cost-stats.js +88 -0
- package/dist/tools/get-cost-stats.js.map +1 -0
- package/dist/tools/get-error-spans.d.ts +8 -0
- package/dist/tools/get-error-spans.d.ts.map +1 -0
- package/dist/tools/get-error-spans.js +25 -0
- package/dist/tools/get-error-spans.js.map +1 -0
- package/dist/tools/get-insights.d.ts.map +1 -1
- package/dist/tools/get-insights.js +74 -109
- package/dist/tools/get-insights.js.map +1 -1
- package/dist/tools/get-latency-stats.d.ts +7 -0
- package/dist/tools/get-latency-stats.d.ts.map +1 -0
- package/dist/tools/get-latency-stats.js +28 -0
- package/dist/tools/get-latency-stats.js.map +1 -0
- package/dist/tools/get-project-summary.d.ts +0 -39
- package/dist/tools/get-project-summary.d.ts.map +1 -1
- package/dist/tools/get-project-summary.js +76 -79
- package/dist/tools/get-project-summary.js.map +1 -1
- package/dist/tools/get-span.d.ts +6 -0
- package/dist/tools/get-span.d.ts.map +1 -0
- package/dist/tools/get-span.js +30 -0
- package/dist/tools/get-span.js.map +1 -0
- package/dist/tools/get-token-usage.d.ts +7 -0
- package/dist/tools/get-token-usage.d.ts.map +1 -0
- package/dist/tools/get-token-usage.js +25 -0
- package/dist/tools/get-token-usage.js.map +1 -0
- package/dist/tools/get-trace.d.ts +6 -0
- package/dist/tools/get-trace.d.ts.map +1 -0
- package/dist/tools/get-trace.js +28 -0
- package/dist/tools/get-trace.js.map +1 -0
- package/dist/tools/list-spans.d.ts +15 -0
- package/dist/tools/list-spans.d.ts.map +1 -0
- package/dist/tools/list-spans.js +19 -0
- package/dist/tools/list-spans.js.map +1 -0
- package/dist/tools/schemas.d.ts +45 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +86 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/switch-project.d.ts.map +1 -1
- package/dist/tools/switch-project.js +36 -4
- package/dist/tools/switch-project.js.map +1 -1
- package/package.json +2 -2
- package/dist/tools/annotate-thread.d.ts +0 -11
- package/dist/tools/annotate-thread.d.ts.map +0 -1
- package/dist/tools/annotate-thread.js +0 -23
- package/dist/tools/annotate-thread.js.map +0 -1
- package/dist/tools/get-event-counts.d.ts +0 -23
- package/dist/tools/get-event-counts.d.ts.map +0 -1
- package/dist/tools/get-event-counts.js +0 -50
- package/dist/tools/get-event-counts.js.map +0 -1
- package/dist/tools/get-ontology.d.ts +0 -9
- package/dist/tools/get-ontology.d.ts.map +0 -1
- package/dist/tools/get-ontology.js +0 -62
- package/dist/tools/get-ontology.js.map +0 -1
- package/dist/tools/get-retention.d.ts +0 -11
- package/dist/tools/get-retention.d.ts.map +0 -1
- package/dist/tools/get-retention.js +0 -87
- package/dist/tools/get-retention.js.map +0 -1
- package/dist/tools/get-top-events.d.ts +0 -11
- package/dist/tools/get-top-events.d.ts.map +0 -1
- package/dist/tools/get-top-events.js +0 -74
- package/dist/tools/get-top-events.js.map +0 -1
- package/dist/tools/get-user-journey.d.ts +0 -10
- package/dist/tools/get-user-journey.d.ts.map +0 -1
- package/dist/tools/get-user-journey.js +0 -143
- package/dist/tools/get-user-journey.js.map +0 -1
- package/dist/tools/update-ontology.d.ts +0 -37
- package/dist/tools/update-ontology.d.ts.map +0 -1
- package/dist/tools/update-ontology.js +0 -51
- package/dist/tools/update-ontology.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated-tools.d.ts","sourceRoot":"","sources":["../../src/tools/deprecated-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAIjF,UAAU,YAAY;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC7C;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAqE3D,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { buildDeprecationShim } from "./deprecated.js";
|
|
2
|
+
const SUNSET_ON = "2026-06-17";
|
|
3
|
+
/**
|
|
4
|
+
* The 6 retired web-analytics tools. Their old registrations in server.ts
|
|
5
|
+
* become handlers that emit the deprecation envelope from
|
|
6
|
+
* `buildDeprecationShim`. After 2026-06-17 these registrations should be
|
|
7
|
+
* deleted outright and callers will see "unknown tool" from the MCP SDK.
|
|
8
|
+
*
|
|
9
|
+
* Spec §7.1 retired list + §8.4 60-day shim window.
|
|
10
|
+
*/
|
|
11
|
+
export const RETIRED_TOOL_SHIMS = {
|
|
12
|
+
get_event_counts: {
|
|
13
|
+
description: "DEPRECATED — web-analytics tool. Returns a deprecation notice. " +
|
|
14
|
+
`Retires on ${SUNSET_ON}. Use list_spans + get_token_usage for LLM-obs equivalents.`,
|
|
15
|
+
handler: buildDeprecationShim({
|
|
16
|
+
toolName: "get_event_counts",
|
|
17
|
+
replacementTools: ["list_spans", "get_token_usage"],
|
|
18
|
+
sunsetOn: SUNSET_ON,
|
|
19
|
+
reason: "Infer pivoted from web-analytics events to LLM-obs spans; event-count aggregation has no direct LLM-obs analogue.",
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
get_retention: {
|
|
23
|
+
description: `DEPRECATED — web-analytics tool. Retires on ${SUNSET_ON}. Cohort retention has no LLM-obs equivalent.`,
|
|
24
|
+
handler: buildDeprecationShim({
|
|
25
|
+
toolName: "get_retention",
|
|
26
|
+
replacementTools: [],
|
|
27
|
+
sunsetOn: SUNSET_ON,
|
|
28
|
+
reason: "Cohort-based retention doesn't map to LLM-obs data; sessions are short-lived, not repeated returns.",
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
get_top_events: {
|
|
32
|
+
description: `DEPRECATED — retires on ${SUNSET_ON}. Use list_spans to inspect recent spans.`,
|
|
33
|
+
handler: buildDeprecationShim({
|
|
34
|
+
toolName: "get_top_events",
|
|
35
|
+
replacementTools: ["list_spans"],
|
|
36
|
+
sunsetOn: SUNSET_ON,
|
|
37
|
+
reason: "Event-count leaderboards don't apply to LLM-obs; a get_top_models tool is planned for v1.1.",
|
|
38
|
+
}),
|
|
39
|
+
},
|
|
40
|
+
get_user_journey: {
|
|
41
|
+
description: `DEPRECATED — retires on ${SUNSET_ON}. Use get_trace (for one trace) or list_spans (filtered by user_id).`,
|
|
42
|
+
handler: buildDeprecationShim({
|
|
43
|
+
toolName: "get_user_journey",
|
|
44
|
+
replacementTools: ["get_trace", "list_spans"],
|
|
45
|
+
sunsetOn: SUNSET_ON,
|
|
46
|
+
reason: "Per-user event journeys are replaced by per-trace span trees (get_trace) and user-filtered span lists (list_spans?user_id=...).",
|
|
47
|
+
}),
|
|
48
|
+
},
|
|
49
|
+
get_ontology: {
|
|
50
|
+
description: `DEPRECATED — retires on ${SUNSET_ON}. No LLM-obs equivalent.`,
|
|
51
|
+
handler: buildDeprecationShim({
|
|
52
|
+
toolName: "get_ontology",
|
|
53
|
+
replacementTools: [],
|
|
54
|
+
sunsetOn: SUNSET_ON,
|
|
55
|
+
reason: "Event ontology (activation/engagement/monetization classification) is a web-analytics concept and doesn't apply to LLM calls.",
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
update_ontology: {
|
|
59
|
+
description: `DEPRECATED — retires on ${SUNSET_ON}. No LLM-obs equivalent.`,
|
|
60
|
+
handler: buildDeprecationShim({
|
|
61
|
+
toolName: "update_ontology",
|
|
62
|
+
replacementTools: [],
|
|
63
|
+
sunsetOn: SUNSET_ON,
|
|
64
|
+
reason: "Event ontology doesn't apply to LLM-obs data.",
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
annotate_thread: {
|
|
68
|
+
description: `DEPRECATED — split into annotate_span + annotate_trace on 2026-04-18. Retires on ${SUNSET_ON}. ` +
|
|
69
|
+
`Use annotate_span(span_id, content) for single-call findings or annotate_trace(trace_id, content) for agent-turn diagnoses.`,
|
|
70
|
+
handler: buildDeprecationShim({
|
|
71
|
+
toolName: "annotate_thread",
|
|
72
|
+
replacementTools: ["annotate_span", "annotate_trace"],
|
|
73
|
+
sunsetOn: SUNSET_ON,
|
|
74
|
+
reason: "Thread-based annotation is replaced by two finer-grained tools: span-level (one LLM call) and trace-level (one agent turn).",
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=deprecated-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated-tools.js","sourceRoot":"","sources":["../../src/tools/deprecated-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAA4B,MAAM,iBAAiB,CAAC;AAEjF,MAAM,SAAS,GAAG,YAAY,CAAC;AAO/B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAiC;IAC9D,gBAAgB,EAAE;QAChB,WAAW,EACT,iEAAiE;YACjE,cAAc,SAAS,6DAA6D;QACtF,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,kBAAkB;YAC5B,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;YACnD,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,mHAAmH;SAC5H,CAAC;KACH;IACD,aAAa,EAAE;QACb,WAAW,EACT,+CAA+C,SAAS,+CAA+C;QACzG,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,eAAe;YACzB,gBAAgB,EAAE,EAAE;YACpB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,qGAAqG;SAC9G,CAAC;KACH;IACD,cAAc,EAAE;QACd,WAAW,EAAE,2BAA2B,SAAS,2CAA2C;QAC5F,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,gBAAgB;YAC1B,gBAAgB,EAAE,CAAC,YAAY,CAAC;YAChC,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,6FAA6F;SACtG,CAAC;KACH;IACD,gBAAgB,EAAE;QAChB,WAAW,EAAE,2BAA2B,SAAS,sEAAsE;QACvH,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,kBAAkB;YAC5B,gBAAgB,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;YAC7C,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,iIAAiI;SAC1I,CAAC;KACH;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,2BAA2B,SAAS,0BAA0B;QAC3E,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,cAAc;YACxB,gBAAgB,EAAE,EAAE;YACpB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,+HAA+H;SACxI,CAAC;KACH;IACD,eAAe,EAAE;QACf,WAAW,EAAE,2BAA2B,SAAS,0BAA0B;QAC3E,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,iBAAiB;YAC3B,gBAAgB,EAAE,EAAE;YACpB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,+CAA+C;SACxD,CAAC;KACH;IACD,eAAe,EAAE;QACf,WAAW,EACT,oFAAoF,SAAS,IAAI;YACjG,6HAA6H;QAC/H,OAAO,EAAE,oBAAoB,CAAC;YAC5B,QAAQ,EAAE,iBAAiB;YAC3B,gBAAgB,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;YACrD,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,6HAA6H;SACtI,CAAC;KACH;CACF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for deprecated-tool shims. Phase 4 retires 6 web-analytics tools
|
|
3
|
+
* and splits annotate_thread into annotate_span + annotate_trace. All 7
|
|
4
|
+
* old names become thin handlers that return a deterministic envelope
|
|
5
|
+
* explaining the deprecation and pointing at replacement tools.
|
|
6
|
+
*
|
|
7
|
+
* After `sunset_on`, the server.ts registration should remove these shims
|
|
8
|
+
* entirely and the tools become unregistered (MCP clients get "unknown tool"
|
|
9
|
+
* errors). Spec §8.4.
|
|
10
|
+
*/
|
|
11
|
+
export interface DeprecationShimInput {
|
|
12
|
+
toolName: string;
|
|
13
|
+
replacementTools: string[];
|
|
14
|
+
sunsetOn: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolHandlerResponse {
|
|
18
|
+
content: Array<{
|
|
19
|
+
type: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
}>;
|
|
22
|
+
isError?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function buildDeprecationShim(input: DeprecationShimInput): () => Promise<ToolHandlerResponse>;
|
|
25
|
+
//# sourceMappingURL=deprecated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated.d.ts","sourceRoot":"","sources":["../../src/tools/deprecated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAsCpC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for deprecated-tool shims. Phase 4 retires 6 web-analytics tools
|
|
3
|
+
* and splits annotate_thread into annotate_span + annotate_trace. All 7
|
|
4
|
+
* old names become thin handlers that return a deterministic envelope
|
|
5
|
+
* explaining the deprecation and pointing at replacement tools.
|
|
6
|
+
*
|
|
7
|
+
* After `sunset_on`, the server.ts registration should remove these shims
|
|
8
|
+
* entirely and the tools become unregistered (MCP clients get "unknown tool"
|
|
9
|
+
* errors). Spec §8.4.
|
|
10
|
+
*/
|
|
11
|
+
const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
12
|
+
export function buildDeprecationShim(input) {
|
|
13
|
+
if (!ISO_DATE_RE.test(input.sunsetOn)) {
|
|
14
|
+
throw new Error(`buildDeprecationShim: sunset_on must be YYYY-MM-DD (got "${input.sunsetOn}")`);
|
|
15
|
+
}
|
|
16
|
+
const parsed = new Date(`${input.sunsetOn}T00:00:00Z`);
|
|
17
|
+
if (Number.isNaN(parsed.getTime()) || parsed.toISOString().slice(0, 10) !== input.sunsetOn) {
|
|
18
|
+
throw new Error(`buildDeprecationShim: sunset_on must be a real calendar date (got "${input.sunsetOn}")`);
|
|
19
|
+
}
|
|
20
|
+
const replacementHint = input.replacementTools.length > 0
|
|
21
|
+
? `Use ${input.replacementTools.map((t) => `\`${t}\``).join(" or ")} instead.`
|
|
22
|
+
: "This tool has no direct replacement in the LLM-observability surface.";
|
|
23
|
+
const trimmedReason = input.reason?.trim() ?? "";
|
|
24
|
+
const messageLines = [
|
|
25
|
+
`\`${input.toolName}\` is deprecated and will be removed after ${input.sunsetOn}.`,
|
|
26
|
+
replacementHint,
|
|
27
|
+
trimmedReason ? `Reason: ${trimmedReason}` : "",
|
|
28
|
+
].filter(Boolean);
|
|
29
|
+
const payload = {
|
|
30
|
+
deprecated: true,
|
|
31
|
+
tool_name: input.toolName,
|
|
32
|
+
sunset_on: input.sunsetOn,
|
|
33
|
+
replacement_tools: input.replacementTools,
|
|
34
|
+
reason: input.reason,
|
|
35
|
+
message: messageLines.join(" "),
|
|
36
|
+
};
|
|
37
|
+
return async () => ({
|
|
38
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
39
|
+
isError: true,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=deprecated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecated.js","sourceRoot":"","sources":["../../src/tools/deprecated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAE1C,MAAM,UAAU,oBAAoB,CAClC,KAA2B;IAE3B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,4DAA4D,KAAK,CAAC,QAAQ,IAAI,CAC/E,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,YAAY,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3F,MAAM,IAAI,KAAK,CACb,sEAAsE,KAAK,CAAC,QAAQ,IAAI,CACzF,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GACnB,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAC/B,CAAC,CAAC,OAAO,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;QAC9E,CAAC,CAAC,uEAAuE,CAAC;IAE9E,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjD,MAAM,YAAY,GAAG;QACnB,KAAK,KAAK,CAAC,QAAQ,8CAA8C,KAAK,CAAC,QAAQ,GAAG;QAClF,eAAe;QACf,aAAa,CAAC,CAAC,CAAC,WAAW,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE;KAChD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,OAAO,GAAG;QACd,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,QAAQ;QACzB,SAAS,EAAE,KAAK,CAAC,QAAQ;QACzB,iBAAiB,EAAE,KAAK,CAAC,gBAAgB;QACzC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;KAChC,CAAC;IAEF,OAAO,KAAK,IAAkC,EAAE,CAAC,CAAC;QAChD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACnE,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ApiClient } from "../api-client.js";
|
|
2
|
+
export interface GetCostStatsParams {
|
|
3
|
+
dimension: "model" | "user" | "session" | "feature";
|
|
4
|
+
time_window: "1h" | "6h" | "24h" | "7d" | "30d";
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Compute query-time cost per dimension group by joining raw token totals
|
|
8
|
+
* against @inferevents/shared PRICING_TABLE.
|
|
9
|
+
*
|
|
10
|
+
* Contract — silent-zero defense:
|
|
11
|
+
* - Unknown (provider, model) pair → cost_usd=null on that per-model breakdown
|
|
12
|
+
* AND null-propagates to the group total AND emits a named warning. NEVER
|
|
13
|
+
* silently zero-cost an unknown model.
|
|
14
|
+
* - Ollama short-circuits to $0 (free by design). That is legitimate zero,
|
|
15
|
+
* NOT missing pricing. No warning is emitted for ollama models.
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleGetCostStats(client: ApiClient, params: GetCostStatsParams): Promise<string>;
|
|
18
|
+
//# sourceMappingURL=get-cost-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-cost-stats.d.ts","sourceRoot":"","sources":["../../src/tools/get-cost-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAIlD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACpD,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;CACjD;AA6BD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAsFjB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { computeCostUsd } from "@inferevents/shared";
|
|
2
|
+
import { wrapResult, toolResponseText } from "../tool-result.js";
|
|
3
|
+
/**
|
|
4
|
+
* Compute query-time cost per dimension group by joining raw token totals
|
|
5
|
+
* against @inferevents/shared PRICING_TABLE.
|
|
6
|
+
*
|
|
7
|
+
* Contract — silent-zero defense:
|
|
8
|
+
* - Unknown (provider, model) pair → cost_usd=null on that per-model breakdown
|
|
9
|
+
* AND null-propagates to the group total AND emits a named warning. NEVER
|
|
10
|
+
* silently zero-cost an unknown model.
|
|
11
|
+
* - Ollama short-circuits to $0 (free by design). That is legitimate zero,
|
|
12
|
+
* NOT missing pricing. No warning is emitted for ollama models.
|
|
13
|
+
*/
|
|
14
|
+
export async function handleGetCostStats(client, params) {
|
|
15
|
+
const result = await client.getCostStats(params);
|
|
16
|
+
const rows = result.rows;
|
|
17
|
+
const warnings = [];
|
|
18
|
+
const caveats = [
|
|
19
|
+
`Costs computed at query time from @inferevents/shared PRICING_TABLE (version ${result.pricing_source_version}). The spans.cost_usd column is not populated at ingest.`,
|
|
20
|
+
`Zero-cost entries for provider="ollama" are legitimate (Ollama is free by design), not a missing-pricing warning.`,
|
|
21
|
+
];
|
|
22
|
+
const missingModels = new Set();
|
|
23
|
+
const byKey = new Map();
|
|
24
|
+
for (const r of rows) {
|
|
25
|
+
const key = r.dimension_key;
|
|
26
|
+
let group = byKey.get(key);
|
|
27
|
+
if (!group) {
|
|
28
|
+
group = { key, count: 0, input_tokens: 0, output_tokens: 0, cost_usd: 0, per_model_breakdown: [] };
|
|
29
|
+
byKey.set(key, group);
|
|
30
|
+
}
|
|
31
|
+
group.count += r.count;
|
|
32
|
+
group.input_tokens += r.input_tokens;
|
|
33
|
+
group.output_tokens += r.output_tokens;
|
|
34
|
+
const cost = computeCostUsd(r.provider, r.model, r.input_tokens, r.output_tokens);
|
|
35
|
+
if (cost === null) {
|
|
36
|
+
// Missing from PRICING_TABLE. Ollama short-circuits to 0 inside computeCostUsd,
|
|
37
|
+
// so null here strictly means "unknown (provider, model)".
|
|
38
|
+
missingModels.add(`${r.provider}:${r.model}`);
|
|
39
|
+
group.cost_usd = null; // null propagates up — never silently zero.
|
|
40
|
+
}
|
|
41
|
+
else if (group.cost_usd !== null) {
|
|
42
|
+
group.cost_usd += cost;
|
|
43
|
+
}
|
|
44
|
+
group.per_model_breakdown.push({
|
|
45
|
+
provider: r.provider,
|
|
46
|
+
model: r.model,
|
|
47
|
+
count: r.count,
|
|
48
|
+
input_tokens: r.input_tokens,
|
|
49
|
+
output_tokens: r.output_tokens,
|
|
50
|
+
cost_usd: cost,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
for (const missing of missingModels) {
|
|
54
|
+
warnings.push(`Model "${missing}" not in pricing table — cost computation skipped. Update @inferevents/shared PRICING_TABLE to include this model's input/output rates.`);
|
|
55
|
+
}
|
|
56
|
+
for (const group of byKey.values()) {
|
|
57
|
+
if (group.cost_usd === null && params.dimension !== "model") {
|
|
58
|
+
const affected = group.per_model_breakdown.filter((b) => b.cost_usd === null).map((b) => b.model);
|
|
59
|
+
warnings.push(`${params.dimension}="${group.key}" has partial cost (cannot sum to total) because these models lack pricing: ${affected.join(", ")}.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (byKey.size === 0) {
|
|
63
|
+
warnings.push(`No cost data for dimension=${params.dimension} over the last ${params.time_window}.`);
|
|
64
|
+
}
|
|
65
|
+
// Sort: higher cost first. Null-cost groups sink to the end so missing-pricing
|
|
66
|
+
// entries don't fake-top the ranking and mislead the agent.
|
|
67
|
+
const groups = Array.from(byKey.values()).sort((a, b) => {
|
|
68
|
+
if (a.cost_usd === null && b.cost_usd === null)
|
|
69
|
+
return 0;
|
|
70
|
+
if (a.cost_usd === null)
|
|
71
|
+
return 1;
|
|
72
|
+
if (b.cost_usd === null)
|
|
73
|
+
return -1;
|
|
74
|
+
return b.cost_usd - a.cost_usd;
|
|
75
|
+
});
|
|
76
|
+
return toolResponseText(wrapResult({
|
|
77
|
+
primary: {
|
|
78
|
+
dimension: result.dimension,
|
|
79
|
+
time_window: result.time_window,
|
|
80
|
+
groups,
|
|
81
|
+
pricing_source_version: result.pricing_source_version,
|
|
82
|
+
},
|
|
83
|
+
source: "spans",
|
|
84
|
+
warnings,
|
|
85
|
+
caveats,
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=get-cost-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-cost-stats.js","sourceRoot":"","sources":["../../src/tools/get-cost-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ApiClient } from "../api-client.js";
|
|
2
|
+
export interface GetErrorSpansParams {
|
|
3
|
+
time_window?: "1h" | "6h" | "24h" | "7d" | "30d";
|
|
4
|
+
limit?: number;
|
|
5
|
+
cursor?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function handleGetErrorSpans(client: ApiClient, params: GetErrorSpansParams): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=get-error-spans.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-error-spans.d.ts","sourceRoot":"","sources":["../../src/tools/get-error-spans.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { wrapResult, toolResponseText } from "../tool-result.js";
|
|
2
|
+
export async function handleGetErrorSpans(client, params) {
|
|
3
|
+
const result = await client.getErrorSpans(params);
|
|
4
|
+
const warnings = [];
|
|
5
|
+
const caveats = [
|
|
6
|
+
"Includes status_code >= 400 AND stream_truncated = true rows (truncated streams are effective failures even at HTTP 200).",
|
|
7
|
+
];
|
|
8
|
+
const retryStormCount = result.spans.filter((s) => s.attempt_count > 1).length;
|
|
9
|
+
if (retryStormCount > 0) {
|
|
10
|
+
warnings.push(`${retryStormCount} failure(s) were retried (attempt_count > 1). Check upstream stability or client retry configuration.`);
|
|
11
|
+
}
|
|
12
|
+
if (result.spans.length === 0) {
|
|
13
|
+
warnings.push(`No errors in the last ${params.time_window ?? "24h"} — either things are stable or no traffic reached the gateway.`);
|
|
14
|
+
}
|
|
15
|
+
if (result.next_cursor !== null) {
|
|
16
|
+
caveats.push(`More results available — call get_error_spans again with cursor="${result.next_cursor}".`);
|
|
17
|
+
}
|
|
18
|
+
return toolResponseText(wrapResult({
|
|
19
|
+
primary: result,
|
|
20
|
+
source: "spans",
|
|
21
|
+
warnings,
|
|
22
|
+
caveats,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=get-error-spans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-error-spans.js","sourceRoot":"","sources":["../../src/tools/get-error-spans.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAQjE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiB,EACjB,MAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAElD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAa;QACxB,2HAA2H;KAC5H,CAAC;IAEF,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/E,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CACX,GAAG,eAAe,uGAAuG,CAC1H,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CACX,yBAAyB,MAAM,CAAC,WAAW,IAAI,KAAK,gEAAgE,CACrH,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,oEAAoE,MAAM,CAAC,WAAW,IAAI,CAC3F,CAAC;IACJ,CAAC;IAED,OAAO,gBAAgB,CACrB,UAAU,CAAC;QACT,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,OAAO;QACf,QAAQ;QACR,OAAO;KACR,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-insights.d.ts","sourceRoot":"","sources":["../../src/tools/get-insights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"get-insights.d.ts","sourceRoot":"","sources":["../../src/tools/get-insights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,eAAO,MAAM,iBAAiB;;CAK7B,CAAC;AAiDF,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,CA2EjB"}
|
|
@@ -1,127 +1,92 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { wrapResult, toolResponseText } from "../tool-result.js";
|
|
2
3
|
export const getInsightsSchema = {
|
|
3
4
|
severity: z
|
|
4
5
|
.enum(["critical", "notable", "informational"])
|
|
5
6
|
.optional()
|
|
6
7
|
.describe("Filter by severity level. Omit to get all unacknowledged insights."),
|
|
7
8
|
};
|
|
9
|
+
function isLlmObsShape(ev) {
|
|
10
|
+
return typeof ev.provider === "string" || typeof ev.model === "string";
|
|
11
|
+
}
|
|
12
|
+
function renderEvidence(ev) {
|
|
13
|
+
if (isLlmObsShape(ev)) {
|
|
14
|
+
const parts = [];
|
|
15
|
+
if (ev.provider)
|
|
16
|
+
parts.push(`provider=${ev.provider}`);
|
|
17
|
+
if (ev.model)
|
|
18
|
+
parts.push(`model=${ev.model}`);
|
|
19
|
+
if (ev.feature)
|
|
20
|
+
parts.push(`feature=${ev.feature}`);
|
|
21
|
+
for (const [k, v] of Object.entries(ev)) {
|
|
22
|
+
if (["provider", "model", "feature"].includes(k))
|
|
23
|
+
continue;
|
|
24
|
+
parts.push(`${k}=${typeof v === "number" ? v.toLocaleString() : v}`);
|
|
25
|
+
}
|
|
26
|
+
return parts.join(", ");
|
|
27
|
+
}
|
|
28
|
+
return Object.entries(ev)
|
|
29
|
+
.slice(0, 6)
|
|
30
|
+
.map(([k, v]) => `${k}=${typeof v === "number" ? v.toLocaleString() : v}`)
|
|
31
|
+
.join(", ");
|
|
32
|
+
}
|
|
8
33
|
export async function handleGetInsights(client, params) {
|
|
9
|
-
const result = await client.getInsights({
|
|
10
|
-
|
|
11
|
-
|
|
34
|
+
const result = await client.getInsights({ severity: params.severity });
|
|
35
|
+
const warnings = [];
|
|
36
|
+
const caveats = [];
|
|
12
37
|
if (result.count === 0) {
|
|
13
|
-
|
|
38
|
+
warnings.push("No new insights. Everything looks normal, or there isn't enough data yet (insights activate after first spans arrive).");
|
|
39
|
+
return toolResponseText(wrapResult({
|
|
40
|
+
primary: { insights: [], count: 0, rendered_text: "" },
|
|
41
|
+
source: "insights",
|
|
42
|
+
warnings,
|
|
43
|
+
caveats,
|
|
44
|
+
}));
|
|
14
45
|
}
|
|
15
|
-
const severityIcon = {
|
|
16
|
-
|
|
17
|
-
notable
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
const confidenceLabel = {
|
|
21
|
-
low: "directional, limited data",
|
|
22
|
-
medium: "moderate confidence",
|
|
23
|
-
high: "high confidence",
|
|
24
|
-
};
|
|
25
|
-
// Split into code actions and strategy actions
|
|
26
|
-
const codeActions = result.insights.filter((i) => i.action_type === "code");
|
|
27
|
-
const strategyActions = result.insights.filter((i) => i.action_type === "strategy");
|
|
28
|
-
const unclassified = result.insights.filter((i) => !i.action_type);
|
|
29
|
-
const chart = [
|
|
30
|
-
`${result.count} items need your attention`,
|
|
31
|
-
`${"─".repeat(50)}`,
|
|
46
|
+
const severityIcon = { critical: "!!", notable: "!", informational: "i" };
|
|
47
|
+
const lines = [
|
|
48
|
+
`${result.count} insight(s) — detected anomalies + notable patterns`,
|
|
49
|
+
"─".repeat(60),
|
|
32
50
|
];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
chart.push(` Day ${thread.day_count} — ongoing since ${thread.first_detected_at.split("T")[0]}`);
|
|
44
|
-
}
|
|
45
|
-
if (thread?.latest_annotation) {
|
|
46
|
-
chart.push(` Note: ${thread.latest_annotation}`);
|
|
47
|
-
}
|
|
48
|
-
if (insight.suggested_action) {
|
|
49
|
-
chart.push(` Action: ${insight.suggested_action}`);
|
|
50
|
-
}
|
|
51
|
-
if (insight.correlation_hint) {
|
|
52
|
-
chart.push(` Git hint: ${insight.correlation_hint}`);
|
|
53
|
-
}
|
|
54
|
-
if (insight.related_events.length > 0) {
|
|
55
|
-
chart.push(` Events: ${insight.related_events.join(", ")}`);
|
|
51
|
+
const insights = result.insights;
|
|
52
|
+
for (const ins of insights) {
|
|
53
|
+
const icon = severityIcon[ins.severity] ?? "?";
|
|
54
|
+
lines.push(`[${icon}] ${ins.summary}`);
|
|
55
|
+
const evLine = renderEvidence(ins.evidence);
|
|
56
|
+
if (evLine)
|
|
57
|
+
lines.push(` ${evLine}`);
|
|
58
|
+
if (ins.thread) {
|
|
59
|
+
if (ins.thread.day_count > 1) {
|
|
60
|
+
lines.push(` Day ${ins.thread.day_count} — ongoing since ${ins.thread.first_detected_at.slice(0, 10)}`);
|
|
56
61
|
}
|
|
57
|
-
if (thread) {
|
|
58
|
-
|
|
62
|
+
if (ins.thread.latest_annotation) {
|
|
63
|
+
lines.push(` Note: ${ins.thread.latest_annotation}`);
|
|
59
64
|
}
|
|
60
|
-
|
|
65
|
+
const annotateCall = isLlmObsShape(ins.evidence)
|
|
66
|
+
? ` → annotate_trace("${ins.thread.thread_id}", "<your finding>")`
|
|
67
|
+
: ` → annotate_span("<span_id>", "<your finding>")`;
|
|
68
|
+
lines.push(annotateCall);
|
|
61
69
|
}
|
|
70
|
+
if (ins.suggested_action)
|
|
71
|
+
lines.push(` Action: ${ins.suggested_action}`);
|
|
72
|
+
if (ins.correlation_hint)
|
|
73
|
+
lines.push(` Git hint: ${ins.correlation_hint}`);
|
|
74
|
+
lines.push("");
|
|
62
75
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
for (const insight of strategyActions) {
|
|
68
|
-
const icon = severityIcon[insight.severity] ?? "?";
|
|
69
|
-
const conf = insight.confidence !== "high" ? ` (${confidenceLabel[insight.confidence] ?? ""})` : "";
|
|
70
|
-
chart.push(`[${icon}] ${insight.summary}${conf}`);
|
|
71
|
-
const thread = insight.thread;
|
|
72
|
-
if (thread && thread.day_count > 1) {
|
|
73
|
-
chart.push(` Day ${thread.day_count} — ongoing since ${thread.first_detected_at.split("T")[0]}`);
|
|
74
|
-
}
|
|
75
|
-
if (thread?.latest_annotation) {
|
|
76
|
-
chart.push(` Note: ${thread.latest_annotation}`);
|
|
77
|
-
}
|
|
78
|
-
if (thread) {
|
|
79
|
-
chart.push(` Thread: ${thread.thread_id}`);
|
|
80
|
-
}
|
|
81
|
-
if (insight.suggested_action) {
|
|
82
|
-
chart.push(` Action: ${insight.suggested_action}`);
|
|
83
|
-
}
|
|
84
|
-
chart.push("");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (unclassified.length > 0) {
|
|
88
|
-
chart.push("");
|
|
89
|
-
chart.push("OTHER");
|
|
90
|
-
chart.push("");
|
|
91
|
-
for (const insight of unclassified) {
|
|
92
|
-
const icon = severityIcon[insight.severity] ?? "?";
|
|
93
|
-
chart.push(`[${icon}] ${insight.severity.toUpperCase()}: ${insight.summary}`);
|
|
94
|
-
const evidence = insight.evidence;
|
|
95
|
-
const evidenceStr = Object.entries(evidence)
|
|
96
|
-
.slice(0, 4)
|
|
97
|
-
.map(([k, v]) => `${k}=${typeof v === "number" ? v.toLocaleString() : v}`)
|
|
98
|
-
.join(", ");
|
|
99
|
-
if (evidenceStr) {
|
|
100
|
-
chart.push(` ${evidenceStr}`);
|
|
101
|
-
}
|
|
102
|
-
chart.push("");
|
|
103
|
-
}
|
|
76
|
+
caveats.push("Insights are auto-detected hourly. annotate_trace / annotate_span the findings — they surface in future briefings and in get_project_summary.");
|
|
77
|
+
const legacyCount = insights.filter((i) => !isLlmObsShape(i.evidence)).length;
|
|
78
|
+
if (legacyCount > 0) {
|
|
79
|
+
caveats.push(`${legacyCount} insight(s) still use the legacy event-based schema. Phase 5 cron rewrite will migrate these to LLM-obs shape.`);
|
|
104
80
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"",
|
|
116
|
-
]
|
|
117
|
-
: [
|
|
118
|
-
"Present this briefing to the user exactly as-is. For CODE ACTIONS, use the Git hint to run `git log` and find related commits before presenting. Add the likely cause to each item.",
|
|
119
|
-
"",
|
|
120
|
-
]),
|
|
121
|
-
"```",
|
|
122
|
-
...chart,
|
|
123
|
-
"```",
|
|
124
|
-
].join("\n");
|
|
125
|
-
return output;
|
|
81
|
+
return toolResponseText(wrapResult({
|
|
82
|
+
primary: {
|
|
83
|
+
insights,
|
|
84
|
+
count: result.count,
|
|
85
|
+
rendered_text: lines.join("\n"),
|
|
86
|
+
},
|
|
87
|
+
source: "insights",
|
|
88
|
+
warnings,
|
|
89
|
+
caveats,
|
|
90
|
+
}));
|
|
126
91
|
}
|
|
127
92
|
//# sourceMappingURL=get-insights.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-insights.js","sourceRoot":"","sources":["../../src/tools/get-insights.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"get-insights.js","sourceRoot":"","sources":["../../src/tools/get-insights.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiClient } from "../api-client.js";
|
|
2
|
+
export interface GetLatencyStatsParams {
|
|
3
|
+
dimension: "model" | "user" | "session" | "feature";
|
|
4
|
+
time_window?: "1h" | "6h" | "24h" | "7d" | "30d";
|
|
5
|
+
}
|
|
6
|
+
export declare function handleGetLatencyStats(client: ApiClient, params: GetLatencyStatsParams): Promise<string>;
|
|
7
|
+
//# sourceMappingURL=get-latency-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-latency-stats.d.ts","sourceRoot":"","sources":["../../src/tools/get-latency-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACpD,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;CAClD;AAID,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { wrapResult, toolResponseText } from "../tool-result.js";
|
|
2
|
+
const MIN_SAMPLE = 10;
|
|
3
|
+
export async function handleGetLatencyStats(client, params) {
|
|
4
|
+
const result = await client.getLatencyStats({
|
|
5
|
+
dimension: params.dimension,
|
|
6
|
+
time_window: params.time_window ?? "24h",
|
|
7
|
+
});
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const caveats = [
|
|
10
|
+
`Percentiles use PostgreSQL PERCENTILE_CONT(p) WITHIN GROUP over duration_ms.`,
|
|
11
|
+
`Only successful spans (status_code < 400) are included — error spans skew tails unfairly.`,
|
|
12
|
+
];
|
|
13
|
+
if (result.groups.length === 0) {
|
|
14
|
+
warnings.push(`No data for dimension=${params.dimension} over the last ${params.time_window ?? "24h"}.`);
|
|
15
|
+
}
|
|
16
|
+
for (const g of result.groups) {
|
|
17
|
+
if (g.count < MIN_SAMPLE) {
|
|
18
|
+
warnings.push(`Small sample: ${params.dimension}="${g.key}" has n=${g.count} (< ${MIN_SAMPLE}). Percentiles are directional only.`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return toolResponseText(wrapResult({
|
|
22
|
+
primary: result,
|
|
23
|
+
source: "spans",
|
|
24
|
+
warnings,
|
|
25
|
+
caveats,
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=get-latency-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-latency-stats.js","sourceRoot":"","sources":["../../src/tools/get-latency-stats.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAOjE,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAiB,EACjB,MAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC;QAC1C,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK;KACzC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAa;QACxB,8EAA8E;QAC9E,2FAA2F;KAC5F,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,QAAQ,CAAC,IAAI,CACX,yBAAyB,MAAM,CAAC,SAAS,kBAAkB,MAAM,CAAC,WAAW,IAAI,KAAK,GAAG,CAC1F,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,KAAK,GAAG,UAAU,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CACX,iBAAiB,MAAM,CAAC,SAAS,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,KAAK,OAAO,UAAU,sCAAsC,CACrH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CACrB,UAAU,CAAC;QACT,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,OAAO;QACf,QAAQ;QACR,OAAO;KACR,CAAC,CACH,CAAC;AACJ,CAAC"}
|