@lesto/observability 0.1.1 → 0.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lesto/observability",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "license": "MIT",
5
5
  "description": "Lesto's in-house distributed-tracing core — OpenTelemetry-shaped, with no OpenTelemetry dependency.",
6
6
  "type": "module",
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The shared AI/agent span vocabulary (ADR 0031).
3
+ *
4
+ * Two records of one agent action must agree on what to call things: the
5
+ * (covered) `mcp.tool` span the control plane emits over `@lesto/mcp`'s
6
+ * `dispatch`, and the (preview) `ai.generate` / `ai.tool` spans `@lesto/ai`
7
+ * emits. This module is that one agreement — value-level span names and
8
+ * attribute keys, plus a pure mapper from an MCP audit record's *shape* onto the
9
+ * `mcp.*` attribute bag.
10
+ *
11
+ * It is deliberately *the shared vocabulary the later trace-attachment phases
12
+ * agree on*, NOT a wave keystone (0034-P1 and 0035-P1 import none of it). And it
13
+ * holds the layering line: `@lesto/observability` gains no `@lesto/mcp` and no
14
+ * `@lesto/ai` import — {@link mcpAuditToSpanAttributes} takes a STRUCTURAL record
15
+ * (the same structural-marker discipline ADR 0028 uses), never an imported type,
16
+ * so the dependency graph stays acyclic.
17
+ */
18
+
19
+ /** The span name an `@lesto/ai` model call opens — one per `generateText` turn. */
20
+ export const AI_GENERATE_SPAN = "ai.generate";
21
+
22
+ /** The span name an `@lesto/ai` tool execution opens — one per `runAgent` tool call. */
23
+ export const AI_TOOL_SPAN = "ai.tool";
24
+
25
+ /** The span name a governed MCP dispatch opens — one per audited `@lesto/mcp` tool call. */
26
+ export const MCP_TOOL_SPAN = "mcp.tool";
27
+
28
+ /** Attribute key: the model id a `generateText` call ran against. */
29
+ export const AI_MODEL_ATTR = "ai.model";
30
+
31
+ /** Attribute key: tokens the model read (the parsed prompt `Usage`). */
32
+ export const AI_USAGE_INPUT_TOKENS_ATTR = "ai.usage.input_tokens";
33
+
34
+ /** Attribute key: tokens the model wrote (the parsed completion `Usage`). */
35
+ export const AI_USAGE_OUTPUT_TOKENS_ATTR = "ai.usage.output_tokens";
36
+
37
+ /** Attribute key: why the model stopped (the `StopReason`). */
38
+ export const AI_STOP_REASON_ATTR = "ai.stop_reason";
39
+
40
+ /**
41
+ * Attribute key: whether the span wraps a streamed (`streamText`) or one-shot (`generateText`)
42
+ * model call — a boolean set on EVERY `ai.generate` span (L-1cbabfc0). It exists so a trace query
43
+ * can segment streamed vs one-shot latency, and so a span missing `ai.usage.*`/`ai.stop_reason`
44
+ * is read correctly: expected on a *torn* streamed span (`true`; a complete stream carries them,
45
+ * recovered from `message_delta`), a regression on a one-shot one (`false`), never an
46
+ * undocumented implicit "this was streamed" signal.
47
+ */
48
+ export const AI_STREAMING_ATTR = "ai.streaming";
49
+
50
+ /** Attribute key: the name of the tool a `runAgent` turn invoked. */
51
+ export const AI_TOOL_NAME_ATTR = "ai.tool.name";
52
+
53
+ /** Attribute key: the MCP tool name as dispatched. */
54
+ export const MCP_TOOL_ATTR = "mcp.tool";
55
+
56
+ /** Attribute key: the SHA-256 hex digest of the canonicalized MCP input. */
57
+ export const MCP_INPUT_HASH_ATTR = "mcp.input_hash";
58
+
59
+ /** Attribute key: whether the MCP dispatch returned (`ok`) or threw (`error`). */
60
+ export const MCP_OUTCOME_ATTR = "mcp.outcome";
61
+
62
+ /** Attribute key: the wall-clock duration of the MCP dispatch, in milliseconds. */
63
+ export const MCP_DURATION_MS_ATTR = "mcp.duration_ms";
64
+
65
+ /**
66
+ * The structural shape of an MCP audit record {@link mcpAuditToSpanAttributes}
67
+ * reads — exactly the four fields it maps, declared structurally so
68
+ * `@lesto/observability` imports no `McpAuditRecord` from `@lesto/mcp` (no
69
+ * cross-edge). `@lesto/mcp`'s real record is a structural supertype of this, so
70
+ * the app passes it straight through with no cast.
71
+ */
72
+ export interface McpAuditShape {
73
+ /** The tool name as dispatched. */
74
+ readonly tool: string;
75
+
76
+ /** A SHA-256 hex digest of the canonicalized input. */
77
+ readonly inputHash: string;
78
+
79
+ /** Whether the handler returned (`ok`) or threw (`error`). */
80
+ readonly outcome: "ok" | "error";
81
+
82
+ /** Wall-clock duration of the dispatch, in milliseconds. */
83
+ readonly durationMs: number;
84
+ }
85
+
86
+ /**
87
+ * Map an MCP audit record's shape onto the `mcp.*` attribute bag for its span.
88
+ *
89
+ * Pure and total: the same four fields the mandatory audit already carries become
90
+ * the four `mcp.*` attributes, so the standalone `mcp.tool` span and the audit
91
+ * line read as one record of one action. The input is structural (see
92
+ * {@link McpAuditShape}) — the app hands its real audit record straight through.
93
+ */
94
+ export function mcpAuditToSpanAttributes(record: McpAuditShape): Record<string, unknown> {
95
+ return {
96
+ [MCP_TOOL_ATTR]: record.tool,
97
+ [MCP_INPUT_HASH_ATTR]: record.inputHash,
98
+ [MCP_OUTCOME_ATTR]: record.outcome,
99
+ [MCP_DURATION_MS_ATTR]: record.durationMs,
100
+ };
101
+ }
package/src/index.ts CHANGED
@@ -68,6 +68,27 @@
68
68
  * `traceparent`.
69
69
  */
70
70
 
71
+ // The shared AI/agent span vocabulary (ADR 0031) — the one contract the covered
72
+ // `mcp.tool` span and the preview `ai.*` spans agree on. The mapper takes a
73
+ // STRUCTURAL record, so this gains no `@lesto/mcp`/`@lesto/ai` edge.
74
+ export {
75
+ AI_GENERATE_SPAN,
76
+ AI_MODEL_ATTR,
77
+ AI_STOP_REASON_ATTR,
78
+ AI_STREAMING_ATTR,
79
+ AI_TOOL_NAME_ATTR,
80
+ AI_TOOL_SPAN,
81
+ AI_USAGE_INPUT_TOKENS_ATTR,
82
+ AI_USAGE_OUTPUT_TOKENS_ATTR,
83
+ MCP_DURATION_MS_ATTR,
84
+ MCP_INPUT_HASH_ATTR,
85
+ MCP_OUTCOME_ATTR,
86
+ MCP_TOOL_ATTR,
87
+ MCP_TOOL_SPAN,
88
+ mcpAuditToSpanAttributes,
89
+ } from "./agent-vocabulary";
90
+ export type { McpAuditShape } from "./agent-vocabulary";
91
+
71
92
  export { InMemoryExporter } from "./exporter";
72
93
 
73
94
  export { DEFAULT_MAX_BUFFERED_SPANS, OtlpHttpExporter, otlpTraceRequest } from "./otlp";