@uptimizr/agent-core 1.1.0 → 1.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/AGENTS.md +238 -25
- package/README.md +57 -21
- package/dist/client.d.ts +22 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -10
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +93 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +137 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/index.js.map +1 -1
- package/dist/nonRegistryTools.d.ts +34 -0
- package/dist/nonRegistryTools.d.ts.map +1 -0
- package/dist/nonRegistryTools.js +70 -0
- package/dist/nonRegistryTools.js.map +1 -0
- package/dist/prompt.d.ts +33 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +49 -0
- package/dist/prompt.js.map +1 -0
- package/dist/provider.d.ts +18 -0
- package/dist/provider.d.ts.map +1 -1
- package/dist/providers/anthropic.d.ts +18 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +35 -3
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/openai.d.ts +14 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +23 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/queryTool.d.ts +36 -0
- package/dist/queryTool.d.ts.map +1 -0
- package/dist/queryTool.js +123 -0
- package/dist/queryTool.js.map +1 -0
- package/dist/registryTools.d.ts +23 -1
- package/dist/registryTools.d.ts.map +1 -1
- package/dist/registryTools.js +185 -31
- package/dist/registryTools.js.map +1 -1
- package/dist/skills.d.ts +105 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.generated.d.ts +44 -0
- package/dist/skills.generated.d.ts.map +1 -0
- package/dist/skills.generated.js +511 -0
- package/dist/skills.generated.js.map +1 -0
- package/dist/skills.js +144 -0
- package/dist/skills.js.map +1 -0
- package/dist/tools.d.ts +55 -8
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +41 -1
- package/dist/tools.js.map +1 -1
- package/dist/writeTools.d.ts +68 -0
- package/dist/writeTools.d.ts.map +1 -0
- package/dist/writeTools.js +256 -0
- package/dist/writeTools.js.map +1 -0
- package/llms.txt +164 -15
- package/package.json +7 -5
- package/skills/attention-hotspots/SKILL.md +88 -0
- package/skills/conversion-investigation/SKILL.md +97 -0
- package/skills/performance-regression-triage/SKILL.md +106 -0
- package/skills/weekly-scene-health/SKILL.md +105 -0
- package/skills/xr-comfort-audit/SKILL.md +95 -0
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
* `tool_use` content blocks, and tool results are `tool_result` blocks carried
|
|
7
7
|
* in a following user turn.
|
|
8
8
|
*/
|
|
9
|
+
/**
|
|
10
|
+
* Normalise Anthropic's `usage` into {@link ProviderUsage}, or `undefined` when
|
|
11
|
+
* the response carried none — so a caller can tell "not reported" from zero.
|
|
12
|
+
*/
|
|
13
|
+
export function toProviderUsage(usage) {
|
|
14
|
+
const input = usage?.input_tokens;
|
|
15
|
+
const output = usage?.output_tokens;
|
|
16
|
+
if (typeof input !== "number" && typeof output !== "number")
|
|
17
|
+
return undefined;
|
|
18
|
+
return {
|
|
19
|
+
...(typeof input === "number" ? { inputTokens: input } : {}),
|
|
20
|
+
...(typeof output === "number" ? { outputTokens: output } : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
9
23
|
/**
|
|
10
24
|
* Build the Anthropic request pieces (system prompt, messages, tools) from the
|
|
11
25
|
* agent conversation and tool schemas.
|
|
@@ -73,10 +87,16 @@ export function parseAnthropicCompletion(completion) {
|
|
|
73
87
|
.filter((b) => b.type === "text")
|
|
74
88
|
.map((b) => b.text)
|
|
75
89
|
.join("");
|
|
90
|
+
const usage = toProviderUsage(completion.usage);
|
|
76
91
|
if (toolCalls.length > 0) {
|
|
77
|
-
return {
|
|
92
|
+
return {
|
|
93
|
+
kind: "tool_calls",
|
|
94
|
+
toolCalls,
|
|
95
|
+
...(text ? { content: text } : {}),
|
|
96
|
+
...(usage ? { usage } : {}),
|
|
97
|
+
};
|
|
78
98
|
}
|
|
79
|
-
return { kind: "final", content: text };
|
|
99
|
+
return { kind: "final", content: text, ...(usage ? { usage } : {}) };
|
|
80
100
|
}
|
|
81
101
|
/** Parse a tool block's accumulated JSON input; malformed/empty → `{}`. */
|
|
82
102
|
function parseToolInput(raw) {
|
|
@@ -93,9 +113,20 @@ function parseToolInput(raw) {
|
|
|
93
113
|
/** Create a fresh {@link AnthropicStreamAssembler}. Pure: no I/O, no regex. */
|
|
94
114
|
export function createAnthropicStreamAssembler() {
|
|
95
115
|
const blocks = new Map();
|
|
116
|
+
// Anthropic splits the accounting across the stream: `message_start` reports
|
|
117
|
+
// the prompt tokens and `message_delta` the generated ones as they accrue.
|
|
118
|
+
const usage = {};
|
|
96
119
|
return {
|
|
97
120
|
push(event) {
|
|
98
121
|
const index = typeof event.index === "number" ? event.index : 0;
|
|
122
|
+
const reported = event.message?.usage ?? event.usage;
|
|
123
|
+
if (reported) {
|
|
124
|
+
if (typeof reported.input_tokens === "number")
|
|
125
|
+
usage.input_tokens = reported.input_tokens;
|
|
126
|
+
if (typeof reported.output_tokens === "number") {
|
|
127
|
+
usage.output_tokens = reported.output_tokens;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
99
130
|
if (event.type === "content_block_start" && event.content_block) {
|
|
100
131
|
const start = event.content_block;
|
|
101
132
|
if (start.type === "text") {
|
|
@@ -149,7 +180,8 @@ export function createAnthropicStreamAssembler() {
|
|
|
149
180
|
});
|
|
150
181
|
}
|
|
151
182
|
}
|
|
152
|
-
|
|
183
|
+
const reported = usage.input_tokens != null || usage.output_tokens != null;
|
|
184
|
+
return { content, ...(reported ? { usage } : {}) };
|
|
153
185
|
},
|
|
154
186
|
};
|
|
155
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* OpenAI-compatible `chat.completions.create`. No I/O, no dependencies: just
|
|
6
6
|
* shape mapping, so both adapters agree on tool-calling semantics.
|
|
7
7
|
*/
|
|
8
|
-
import type { AgentMessage, AgentToolSchema, ProviderResponse } from "../provider.js";
|
|
8
|
+
import type { AgentMessage, AgentToolSchema, ProviderResponse, ProviderUsage } from "../provider.js";
|
|
9
9
|
/** OpenAI chat message (request side). */
|
|
10
10
|
export interface OpenAiMessage {
|
|
11
11
|
role: "system" | "user" | "assistant" | "tool";
|
|
@@ -32,6 +32,11 @@ export interface OpenAiTool {
|
|
|
32
32
|
parameters: Record<string, unknown>;
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
/** OpenAI's token accounting, as the chat-completions API spells it. */
|
|
36
|
+
export interface OpenAiUsage {
|
|
37
|
+
prompt_tokens?: number;
|
|
38
|
+
completion_tokens?: number;
|
|
39
|
+
}
|
|
35
40
|
/** The subset of an OpenAI chat-completion response this module reads. */
|
|
36
41
|
export interface OpenAiCompletion {
|
|
37
42
|
choices?: Array<{
|
|
@@ -40,7 +45,13 @@ export interface OpenAiCompletion {
|
|
|
40
45
|
tool_calls?: OpenAiToolCall[] | null;
|
|
41
46
|
};
|
|
42
47
|
}>;
|
|
48
|
+
usage?: OpenAiUsage;
|
|
43
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Normalise OpenAI's `usage` into {@link ProviderUsage}, or `undefined` when the
|
|
52
|
+
* response carried none — so a caller can tell "not reported" from zero.
|
|
53
|
+
*/
|
|
54
|
+
export declare function toProviderUsage(usage: OpenAiUsage | undefined): ProviderUsage | undefined;
|
|
44
55
|
/** Map the agent conversation to OpenAI request messages. */
|
|
45
56
|
export declare function toOpenAiMessages(messages: readonly AgentMessage[]): OpenAiMessage[];
|
|
46
57
|
/** Map the read-only tool schemas to OpenAI `tools`. */
|
|
@@ -57,6 +68,8 @@ export declare function parseOpenAiCompletion(completion: OpenAiCompletion): Pro
|
|
|
57
68
|
* ones append to `function.arguments`. WebLLM's streamed tool calls omit `id`.
|
|
58
69
|
*/
|
|
59
70
|
export interface OpenAiStreamChunk {
|
|
71
|
+
/** Present on the trailing chunk when the endpoint reports streamed usage. */
|
|
72
|
+
usage?: OpenAiUsage;
|
|
60
73
|
choices?: Array<{
|
|
61
74
|
delta?: {
|
|
62
75
|
content?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,gBAAgB,
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,gBAAgB,EAChB,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CACtF;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,OAAO,CAAC,EAAE;YACR,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;SACtC,CAAC;KACH,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAQzF;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,aAAa,EAAE,CAsBnF;AAUD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,GAAG,UAAU,EAAE,CAK7E;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,CAoBpF;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,UAAU,CAAC,EAAE,KAAK,CAAC;gBACjB,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,EAAE,CAAC,EAAE,MAAM,CAAC;gBACZ,IAAI,CAAC,EAAE,UAAU,CAAC;gBAClB,QAAQ,CAAC,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAC;oBAAC,SAAS,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAC;aAClD,CAAC,GAAG,IAAI,CAAC;SACX,CAAC;QACF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAAC;IACvC,MAAM,IAAI,gBAAgB,CAAC;CAC5B;AAED,4EAA4E;AAC5E,wBAAgB,2BAA2B,IAAI,qBAAqB,CAkDnE"}
|
package/dist/providers/openai.js
CHANGED
|
@@ -5,6 +5,20 @@
|
|
|
5
5
|
* OpenAI-compatible `chat.completions.create`. No I/O, no dependencies: just
|
|
6
6
|
* shape mapping, so both adapters agree on tool-calling semantics.
|
|
7
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Normalise OpenAI's `usage` into {@link ProviderUsage}, or `undefined` when the
|
|
10
|
+
* response carried none — so a caller can tell "not reported" from zero.
|
|
11
|
+
*/
|
|
12
|
+
export function toProviderUsage(usage) {
|
|
13
|
+
const input = usage?.prompt_tokens;
|
|
14
|
+
const output = usage?.completion_tokens;
|
|
15
|
+
if (typeof input !== "number" && typeof output !== "number")
|
|
16
|
+
return undefined;
|
|
17
|
+
return {
|
|
18
|
+
...(typeof input === "number" ? { inputTokens: input } : {}),
|
|
19
|
+
...(typeof output === "number" ? { outputTokens: output } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
8
22
|
/** Map the agent conversation to OpenAI request messages. */
|
|
9
23
|
export function toOpenAiMessages(messages) {
|
|
10
24
|
return messages.map((message) => {
|
|
@@ -63,6 +77,7 @@ export function parseOpenAiCompletion(completion) {
|
|
|
63
77
|
const message = completion.choices?.[0]?.message;
|
|
64
78
|
const toolCalls = message?.tool_calls ?? [];
|
|
65
79
|
const content = message?.content ?? "";
|
|
80
|
+
const usage = toProviderUsage(completion.usage);
|
|
66
81
|
if (toolCalls.length > 0) {
|
|
67
82
|
return {
|
|
68
83
|
kind: "tool_calls",
|
|
@@ -72,17 +87,23 @@ export function parseOpenAiCompletion(completion) {
|
|
|
72
87
|
arguments: parseArguments(call.function.arguments),
|
|
73
88
|
})),
|
|
74
89
|
...(content ? { content } : {}),
|
|
90
|
+
...(usage ? { usage } : {}),
|
|
75
91
|
};
|
|
76
92
|
}
|
|
77
|
-
return { kind: "final", content };
|
|
93
|
+
return { kind: "final", content, ...(usage ? { usage } : {}) };
|
|
78
94
|
}
|
|
79
95
|
/** Create a fresh {@link OpenAiStreamAssembler}. Pure: no I/O, no regex. */
|
|
80
96
|
export function createOpenAiStreamAssembler() {
|
|
81
97
|
let content = "";
|
|
82
98
|
// Keyed by `index` so gapped or out-of-order indices still assemble.
|
|
83
99
|
const calls = new Map();
|
|
100
|
+
// An endpoint that reports streamed usage puts it on a trailing chunk with no
|
|
101
|
+
// delta, so it is read before the early return below.
|
|
102
|
+
let usage;
|
|
84
103
|
return {
|
|
85
104
|
push(chunk) {
|
|
105
|
+
if (chunk.usage)
|
|
106
|
+
usage = chunk.usage;
|
|
86
107
|
const delta = chunk.choices?.[0]?.delta;
|
|
87
108
|
if (!delta)
|
|
88
109
|
return "";
|
|
@@ -122,6 +143,7 @@ export function createOpenAiStreamAssembler() {
|
|
|
122
143
|
},
|
|
123
144
|
},
|
|
124
145
|
],
|
|
146
|
+
...(usage ? { usage } : {}),
|
|
125
147
|
};
|
|
126
148
|
},
|
|
127
149
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **The `query` tool** (ADR 0051 §3, design sketch §C.3).
|
|
3
|
+
*
|
|
4
|
+
* One tool whose input *is* the query DSL. Where the generated catalog gives a
|
|
5
|
+
* model seventy tools and asks it to guess which one carries which flag, this
|
|
6
|
+
* gives it one tool and a vocabulary it can read: pick a `metric`, bound it with
|
|
7
|
+
* a `range`, narrow it with that metric's filters, cap it, and choose the result
|
|
8
|
+
* envelope.
|
|
9
|
+
*
|
|
10
|
+
* The canned per-metric tools stay — they are excellent for discovery, and a
|
|
11
|
+
* small model does better with a narrow, obvious tool than with a schema it has
|
|
12
|
+
* to compose. `query` is what the prompts and skills recommend once a question
|
|
13
|
+
* needs a filter the canned tool does not expose.
|
|
14
|
+
*
|
|
15
|
+
* ## Why it is a `GET`
|
|
16
|
+
*
|
|
17
|
+
* The collector serves the DSL on both `POST /api/v1/query` and
|
|
18
|
+
* `GET /api/v1/query?q=<url-encoded JSON>`. This tool uses the GET form, so
|
|
19
|
+
* {@link import("./client.js").CollectorClient} stays what it has always been —
|
|
20
|
+
* a read-only client that performs `GET` and nothing else. That is not a
|
|
21
|
+
* cosmetic preference: the client's inability to send anything but a `GET` is
|
|
22
|
+
* one of the reasons an Uptimizr agent is structurally incapable of writing
|
|
23
|
+
* (ADR 0003 / ADR 0017), and adding a `post()` for one tool would spend that
|
|
24
|
+
* guarantee to save a URL-encode. The collector's 8 KiB cap on `q` is well above
|
|
25
|
+
* any real query — the largest is a twenty-step funnel.
|
|
26
|
+
*/
|
|
27
|
+
import type { ReadTool } from "./tools.js";
|
|
28
|
+
/** The tool name, also the `operationId` of the endpoint it calls. */
|
|
29
|
+
export declare const QUERY_TOOL_NAME = "query";
|
|
30
|
+
/**
|
|
31
|
+
* The single `query` tool. Its `inputSchema` is the DSL itself, so the model
|
|
32
|
+
* sees the same grammar the collector validates and the docs describe — there is
|
|
33
|
+
* no second, paraphrased tool schema to drift.
|
|
34
|
+
*/
|
|
35
|
+
export declare const queryTool: ReadTool;
|
|
36
|
+
//# sourceMappingURL=queryTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryTool.d.ts","sourceRoot":"","sources":["../src/queryTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,YAAY,CAAC;AAE5D,sEAAsE;AACtE,eAAO,MAAM,eAAe,UAAU,CAAC;AAmFvC;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,QAWvB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **The `query` tool** (ADR 0051 §3, design sketch §C.3).
|
|
3
|
+
*
|
|
4
|
+
* One tool whose input *is* the query DSL. Where the generated catalog gives a
|
|
5
|
+
* model seventy tools and asks it to guess which one carries which flag, this
|
|
6
|
+
* gives it one tool and a vocabulary it can read: pick a `metric`, bound it with
|
|
7
|
+
* a `range`, narrow it with that metric's filters, cap it, and choose the result
|
|
8
|
+
* envelope.
|
|
9
|
+
*
|
|
10
|
+
* The canned per-metric tools stay — they are excellent for discovery, and a
|
|
11
|
+
* small model does better with a narrow, obvious tool than with a schema it has
|
|
12
|
+
* to compose. `query` is what the prompts and skills recommend once a question
|
|
13
|
+
* needs a filter the canned tool does not expose.
|
|
14
|
+
*
|
|
15
|
+
* ## Why it is a `GET`
|
|
16
|
+
*
|
|
17
|
+
* The collector serves the DSL on both `POST /api/v1/query` and
|
|
18
|
+
* `GET /api/v1/query?q=<url-encoded JSON>`. This tool uses the GET form, so
|
|
19
|
+
* {@link import("./client.js").CollectorClient} stays what it has always been —
|
|
20
|
+
* a read-only client that performs `GET` and nothing else. That is not a
|
|
21
|
+
* cosmetic preference: the client's inability to send anything but a `GET` is
|
|
22
|
+
* one of the reasons an Uptimizr agent is structurally incapable of writing
|
|
23
|
+
* (ADR 0003 / ADR 0017), and adding a `post()` for one tool would spend that
|
|
24
|
+
* guarantee to save a URL-encode. The collector's 8 KiB cap on `q` is well above
|
|
25
|
+
* any real query — the largest is a twenty-step funnel.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from "zod";
|
|
28
|
+
import { queryV1Schema } from "@uptimizr/schema";
|
|
29
|
+
import { allMetrics } from "@uptimizr/metrics";
|
|
30
|
+
/** The tool name, also the `operationId` of the endpoint it calls. */
|
|
31
|
+
export const QUERY_TOOL_NAME = "query";
|
|
32
|
+
/** The collector path the tool reads, root-relative like every other tool's. */
|
|
33
|
+
const QUERY_PATH = "api/v1/query";
|
|
34
|
+
/**
|
|
35
|
+
* The agent-facing description.
|
|
36
|
+
*
|
|
37
|
+
* It says six things a model needs and cannot infer from a JSON Schema: where
|
|
38
|
+
* the metric vocabulary comes from (so it looks an id up rather than inventing
|
|
39
|
+
* one), that `range` is not optional, how to read the default envelope, that
|
|
40
|
+
* `compare` will do the arithmetic it would otherwise do in prose, that
|
|
41
|
+
* `explain` exists at all, and that a summary row already carries the query to
|
|
42
|
+
* drill into it. The last three are the ones a model never discovers on its own:
|
|
43
|
+
* it will subtract two results by hand, report a zero it cannot account for, and
|
|
44
|
+
* rebuild a filter it was handed — every time — unless the tool says otherwise.
|
|
45
|
+
*/
|
|
46
|
+
function describeQueryTool() {
|
|
47
|
+
const known = new Set(allMetrics().map((metric) => metric.id));
|
|
48
|
+
const examples = ["top_meshes", "perf_summary", "mesh_sources", "timeseries"]
|
|
49
|
+
.filter((id) => known.has(id))
|
|
50
|
+
.map((id) => `\`${id}\``)
|
|
51
|
+
.join(", ");
|
|
52
|
+
return ("Run any Uptimizr metric in one validated request: choose the `metric`, bound it with a " +
|
|
53
|
+
"`range` (required, epoch milliseconds), narrow it with the filters that metric declares, " +
|
|
54
|
+
"cap it with `limit`, and choose the result envelope with `format`.\n\n" +
|
|
55
|
+
"Metric ids come from the registry — read the `uptimizr://capabilities` resource (or the " +
|
|
56
|
+
"collector's `GET /api/v1/openapi.json`) for the full list, which also names each metric's " +
|
|
57
|
+
`filters, its row columns and their units. Examples: ${examples}.\n\n` +
|
|
58
|
+
'How to read it: the default `format: "table"` returns `{ meta, rows }`, where `meta` ' +
|
|
59
|
+
"carries the window, the filters that were applied, the sample size behind the answer and " +
|
|
60
|
+
"whether the result was truncated — read it before quoting a number. `summary` returns a " +
|
|
61
|
+
"bounded digest (top rows, a trend, or merged spatial clusters) with shares and a " +
|
|
62
|
+
"plain-language reading; prefer it for a heatmap or a long leaderboard. `full` returns the " +
|
|
63
|
+
"bare rows.\n\n" +
|
|
64
|
+
"What changed: set `compare` to another `{ range }` or `{ segment }` and the result comes " +
|
|
65
|
+
"back already joined on the dimension key — `{ current, previous, delta, deltaPct }` per " +
|
|
66
|
+
"row, with a significance test where the measure is a count and both windows are big " +
|
|
67
|
+
"enough. Never run two queries and subtract them yourself.\n\n" +
|
|
68
|
+
"Can you trust it: set `explain: true` and the response is the plan instead of the rows — " +
|
|
69
|
+
"which compiler would run, the SQL with its parameters left unbound, how much data the " +
|
|
70
|
+
"window holds, and every reason the answer might mislead (a capture channel that is " +
|
|
71
|
+
"switched off, a sample below the metric's own minimum, a result cut off by `limit`). Worth " +
|
|
72
|
+
"one call before reporting a zero.\n\n" +
|
|
73
|
+
"Narrowing down: every row of a `summary` carries `drillQuery` — the whole query, narrowed " +
|
|
74
|
+
"to that row, ready to send straight back. Use it rather than rebuilding the query.\n\n" +
|
|
75
|
+
"Caveats:\n" +
|
|
76
|
+
"- Naming a metric, dimension or filter that does not exist is an error that names what the " +
|
|
77
|
+
"metric does accept — read it rather than guessing again.\n" +
|
|
78
|
+
"- `dimensions` may be any subset a metric declares **when** its measure is a portable count " +
|
|
79
|
+
"(event counts, mesh and interaction tallies, input actions, camera gestures). A spatial " +
|
|
80
|
+
"heatmap or a percentile is computed at one fixed grain and refuses anything else by name.\n" +
|
|
81
|
+
"- `order` takes a measure column, not a label, and only where the result is a ranked list.");
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The `{ result }` envelope the tool advertises.
|
|
85
|
+
*
|
|
86
|
+
* The per-metric tools always return `{ rows }`, because their result is always
|
|
87
|
+
* a list of one metric's rows. This tool's shape is chosen by `format`, and the
|
|
88
|
+
* three envelopes are defined once in `@uptimizr/metrics` — but they are
|
|
89
|
+
* parameterised by the answering metric's row schema, which this tool only
|
|
90
|
+
* learns at call time. Restating two
|
|
91
|
+
* hundred lines of envelope schema here to dodge that dependency would create
|
|
92
|
+
* exactly the second definition ADR 0051 §1 exists to prevent, and an MCP client
|
|
93
|
+
* validating against a stale copy would reject a perfectly good answer.
|
|
94
|
+
*
|
|
95
|
+
* So the advertised schema is one described key, and the **response describes
|
|
96
|
+
* itself**: a `table` carries `meta.metric`, `meta.sampleSize` and
|
|
97
|
+
* `meta.truncated`; a `summary` carries `kind`, `metric`, `measure`, `reading`
|
|
98
|
+
* and `caveats`.
|
|
99
|
+
*/
|
|
100
|
+
const outputSchema = z.object({
|
|
101
|
+
result: z
|
|
102
|
+
.unknown()
|
|
103
|
+
.describe("The result, shaped by `format`: `table` → `{ meta, rows }` (the default), `summary` → a " +
|
|
104
|
+
"bounded digest with `kind`, `reading` and `caveats`, `full` → the bare rows."),
|
|
105
|
+
});
|
|
106
|
+
/**
|
|
107
|
+
* The single `query` tool. Its `inputSchema` is the DSL itself, so the model
|
|
108
|
+
* sees the same grammar the collector validates and the docs describe — there is
|
|
109
|
+
* no second, paraphrased tool schema to drift.
|
|
110
|
+
*/
|
|
111
|
+
export const queryTool = {
|
|
112
|
+
name: QUERY_TOOL_NAME,
|
|
113
|
+
title: "Run an analytics query",
|
|
114
|
+
description: describeQueryTool(),
|
|
115
|
+
inputSchema: queryV1Schema.shape,
|
|
116
|
+
outputSchema,
|
|
117
|
+
buildRequest: (args) => ({
|
|
118
|
+
path: QUERY_PATH,
|
|
119
|
+
params: { q: JSON.stringify(args) },
|
|
120
|
+
}),
|
|
121
|
+
structuredContent: (data) => ({ result: data }),
|
|
122
|
+
};
|
|
123
|
+
//# sourceMappingURL=queryTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryTool.js","sourceRoot":"","sources":["../src/queryTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAEvC,gFAAgF;AAChF,MAAM,UAAU,GAAG,cAAc,CAAC;AAElC;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB;IACxB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAY,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,CAAC;SAC1E,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAC7B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,CACL,yFAAyF;QACzF,2FAA2F;QAC3F,wEAAwE;QACxE,0FAA0F;QAC1F,4FAA4F;QAC5F,uDAAuD,QAAQ,OAAO;QACtE,uFAAuF;QACvF,2FAA2F;QAC3F,0FAA0F;QAC1F,mFAAmF;QACnF,4FAA4F;QAC5F,gBAAgB;QAChB,2FAA2F;QAC3F,0FAA0F;QAC1F,sFAAsF;QACtF,+DAA+D;QAC/D,2FAA2F;QAC3F,wFAAwF;QACxF,qFAAqF;QACrF,6FAA6F;QAC7F,uCAAuC;QACvC,4FAA4F;QAC5F,wFAAwF;QACxF,YAAY;QACZ,6FAA6F;QAC7F,4DAA4D;QAC5D,8FAA8F;QAC9F,0FAA0F;QAC1F,6FAA6F;QAC7F,4FAA4F,CAC7F,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,MAAM,EAAE,CAAC;SACN,OAAO,EAAE;SACT,QAAQ,CACP,0FAA0F;QACxF,8EAA8E,CACjF;CACJ,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAa;IACjC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,wBAAwB;IAC/B,WAAW,EAAE,iBAAiB,EAAE;IAChC,WAAW,EAAE,aAAa,CAAC,KAAK;IAChC,YAAY;IACZ,YAAY,EAAE,CAAC,IAA6B,EAAmB,EAAE,CAAC,CAAC;QACjE,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;KACpC,CAAC;IACF,iBAAiB,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;CACzD,CAAC"}
|
package/dist/registryTools.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* | `description` | `description` + `interpretation` + `caveats` |
|
|
18
18
|
* | `inputSchema` | `filters` + `endpoint.pathParams`, via {@link FILTER_FIELDS} |
|
|
19
19
|
* | `buildRequest` | `endpoint.path` (with `:param` substitution) + `filters` |
|
|
20
|
-
* | `outputSchema` | `row`,
|
|
20
|
+
* | `outputSchema` | `row`, in the `format` result envelope (ADR 0051 §2) |
|
|
21
21
|
*
|
|
22
22
|
* **Browser safety (ADR 0050).** This module imports `@uptimizr/metrics` — the
|
|
23
23
|
* registry's own dependency-free package, whose only runtime dependencies are
|
|
@@ -30,6 +30,21 @@
|
|
|
30
30
|
*/
|
|
31
31
|
import { type MetricDefinition } from "@uptimizr/metrics";
|
|
32
32
|
import type { ReadTool } from "./tools.js";
|
|
33
|
+
/**
|
|
34
|
+
* The result envelope a generated tool asks the collector for when the caller
|
|
35
|
+
* names none (#336).
|
|
36
|
+
*
|
|
37
|
+
* `table` — the rows *plus* the `meta` block that says which metric answered,
|
|
38
|
+
* over what range, with which filters, how many rows came back and whether the
|
|
39
|
+
* row cap truncated them. An agent that omits `format` therefore gets the
|
|
40
|
+
* context it needs to judge the answer instead of a bare, unlabelled array; a
|
|
41
|
+
* caller that wants the old shape asks for `full` explicitly.
|
|
42
|
+
*
|
|
43
|
+
* The default lives **here, in the tool**, and travels as an explicit
|
|
44
|
+
* `format=table` on the wire. The collector's own default is still `full`, so
|
|
45
|
+
* the dashboard — which never sends the parameter — cannot be affected.
|
|
46
|
+
*/
|
|
47
|
+
export declare const DEFAULT_TOOL_FORMAT: "table";
|
|
33
48
|
/**
|
|
34
49
|
* Compose the agent-facing tool description: what the metric measures, how to
|
|
35
50
|
* read the result, and the caveats that decide how far to trust it. All three
|
|
@@ -47,6 +62,13 @@ export declare function metricToTool(metric: MetricDefinition): ReadTool | undef
|
|
|
47
62
|
* Generate the read-only tool catalog from the metric registry: one tool per
|
|
48
63
|
* registry entry that has a collector endpoint, in registry declaration order.
|
|
49
64
|
*
|
|
65
|
+
* **Capability-blind by design.** It generates a tool for every endpoint,
|
|
66
|
+
* whatever `endpoint.capability` says, because generation and *exposure* are
|
|
67
|
+
* separate decisions: `tools.ts` partitions the result into the `query` catalog
|
|
68
|
+
* (`readTools`) and the `query:raw` one (`rawTools`), and the host decides which
|
|
69
|
+
* of those a given API key may see (ADR 0051 §7). Pass a filtered metric list to
|
|
70
|
+
* generate only part of the catalog.
|
|
71
|
+
*
|
|
50
72
|
* Pure — it reads definitions only and never touches a collector — so the whole
|
|
51
73
|
* catalog is unit-testable without a live server.
|
|
52
74
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registryTools.d.ts","sourceRoot":"","sources":["../src/registryTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;
|
|
1
|
+
{"version":3,"file":"registryTools.d.ts","sourceRoot":"","sources":["../src/registryTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAMH,OAAO,EAOL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,YAAY,CAAC;AAkB5D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAG,OAAgB,CAAC;AAqapD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAO/D;AAYD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CA8E3E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,SAAS,gBAAgB,EAAiB,GAClD,SAAS,QAAQ,EAAE,CAOrB"}
|