@contractspec/lib.ai-agent 2.0.0 → 2.1.1
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/agent/agent-factory.js +255 -35
- package/dist/agent/contract-spec-agent.d.ts +3 -1
- package/dist/agent/contract-spec-agent.js +255 -35
- package/dist/agent/index.js +255 -35
- package/dist/agent/json-runner.js +255 -35
- package/dist/agent/unified-agent.js +255 -35
- package/dist/node/agent/agent-factory.js +255 -35
- package/dist/node/agent/contract-spec-agent.js +255 -35
- package/dist/node/agent/index.js +255 -35
- package/dist/node/agent/json-runner.js +255 -35
- package/dist/node/agent/unified-agent.js +255 -35
- package/dist/node/telemetry/adapter.js +84 -4
- package/dist/node/telemetry/index.js +165 -15
- package/dist/node/telemetry/posthog.js +81 -11
- package/dist/telemetry/adapter.d.ts +10 -1
- package/dist/telemetry/adapter.js +84 -4
- package/dist/telemetry/adapter.test.d.ts +1 -0
- package/dist/telemetry/index.js +165 -15
- package/dist/telemetry/posthog-types.d.ts +12 -0
- package/dist/telemetry/posthog.js +81 -11
- package/package.json +6 -6
package/dist/telemetry/index.js
CHANGED
|
@@ -14,24 +14,78 @@ var __require = import.meta.require;
|
|
|
14
14
|
|
|
15
15
|
// src/telemetry/adapter.ts
|
|
16
16
|
function parseAgentId(agentId) {
|
|
17
|
-
const match = agentId.match(/^(.+)\.v(\
|
|
17
|
+
const match = agentId.match(/^(.+)\.v(\d+)$/);
|
|
18
18
|
if (match) {
|
|
19
19
|
return { name: match[1], version: match[2] };
|
|
20
20
|
}
|
|
21
21
|
return { name: agentId, version: "1.0.0" };
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
function getRecord(value) {
|
|
24
|
+
return value && typeof value === "object" ? value : undefined;
|
|
25
|
+
}
|
|
26
|
+
function getStepResponse(step) {
|
|
27
|
+
const response = getRecord(step.response);
|
|
28
|
+
if (!response)
|
|
29
|
+
return;
|
|
30
|
+
return {
|
|
31
|
+
id: response["id"],
|
|
32
|
+
modelId: response["modelId"],
|
|
33
|
+
timestamp: response["timestamp"],
|
|
34
|
+
headers: response["headers"],
|
|
35
|
+
body: response["body"],
|
|
36
|
+
messages: response["messages"]
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function getRequestBodyValue(request, key) {
|
|
40
|
+
const body = request?.["body"];
|
|
41
|
+
if (!body)
|
|
42
|
+
return;
|
|
43
|
+
if (typeof body === "string") {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(body);
|
|
46
|
+
return typeof parsed[key] === "string" ? parsed[key] : undefined;
|
|
47
|
+
} catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const record = getRecord(body);
|
|
52
|
+
return typeof record?.[key] === "string" ? record[key] : undefined;
|
|
53
|
+
}
|
|
54
|
+
async function trackAgentStep(collector, agentId, step, durationMs, context) {
|
|
24
55
|
const { name, version } = parseAgentId(agentId);
|
|
56
|
+
const response = getStepResponse(step);
|
|
57
|
+
const providerMetadata = step.providerMetadata;
|
|
58
|
+
const warnings = step.warnings;
|
|
59
|
+
const rawFinishReason = step.rawFinishReason;
|
|
60
|
+
const request = getRecord(step.request);
|
|
61
|
+
const traceId = context?.traceId ?? getRequestBodyValue(request, "$ai_trace_id");
|
|
62
|
+
const sessionId = context?.sessionId ?? getRequestBodyValue(request, "$ai_session_id");
|
|
63
|
+
const parentSpanId = response?.id;
|
|
25
64
|
for (const toolCall of step.toolCalls ?? []) {
|
|
65
|
+
const toolResult = step.toolResults?.find((r) => r.toolCallId === toolCall.toolCallId);
|
|
66
|
+
const toolError = getRecord(toolResult?.output)?.["error"];
|
|
26
67
|
const toolSample = {
|
|
27
68
|
operation: { name: `${name}.${toolCall.toolName}`, version },
|
|
28
69
|
durationMs: durationMs ?? 0,
|
|
29
70
|
success: step.toolResults?.some((r) => r.toolCallId === toolCall.toolCallId && r.output !== undefined) ?? false,
|
|
30
71
|
timestamp: new Date,
|
|
31
72
|
metadata: {
|
|
73
|
+
telemetryEvent: "span",
|
|
74
|
+
traceId,
|
|
75
|
+
sessionId,
|
|
76
|
+
spanId: toolCall.toolCallId,
|
|
77
|
+
parentSpanId,
|
|
78
|
+
spanName: `tool.${toolCall.toolName}`,
|
|
32
79
|
agentId,
|
|
80
|
+
actorId: context?.actorId,
|
|
81
|
+
tenantId: context?.tenantId,
|
|
82
|
+
stepIndex: context?.stepIndex,
|
|
33
83
|
toolName: toolCall.toolName,
|
|
34
|
-
|
|
84
|
+
toolCallArgs: toolCall.input,
|
|
85
|
+
toolResultOutput: toolResult?.output,
|
|
86
|
+
errorMessage: typeof toolError === "string" ? toolError : typeof toolResult?.output === "string" ? toolResult.output : undefined,
|
|
87
|
+
finishReason: step.finishReason,
|
|
88
|
+
rawFinishReason
|
|
35
89
|
}
|
|
36
90
|
};
|
|
37
91
|
await collector.collect(toolSample);
|
|
@@ -42,10 +96,36 @@ async function trackAgentStep(collector, agentId, step, durationMs) {
|
|
|
42
96
|
success: step.finishReason !== "error",
|
|
43
97
|
timestamp: new Date,
|
|
44
98
|
metadata: {
|
|
99
|
+
telemetryEvent: "generation",
|
|
100
|
+
traceId,
|
|
101
|
+
sessionId,
|
|
102
|
+
spanId: response?.id,
|
|
103
|
+
spanName: `agent.${name}.step`,
|
|
45
104
|
agentId,
|
|
105
|
+
actorId: context?.actorId,
|
|
106
|
+
tenantId: context?.tenantId,
|
|
107
|
+
stepIndex: context?.stepIndex,
|
|
108
|
+
stepStartedAt: context?.stepStartedAt,
|
|
46
109
|
finishReason: step.finishReason,
|
|
110
|
+
rawFinishReason,
|
|
47
111
|
tokenUsage: step.usage,
|
|
48
|
-
|
|
112
|
+
totalUsage: step.totalUsage,
|
|
113
|
+
providerMetadata,
|
|
114
|
+
warnings,
|
|
115
|
+
stepText: step.text,
|
|
116
|
+
stepReasoningText: step.reasoningText,
|
|
117
|
+
responseId: response?.id,
|
|
118
|
+
responseModelId: response?.modelId,
|
|
119
|
+
responseTimestamp: response?.timestamp,
|
|
120
|
+
responseHeaders: response?.headers,
|
|
121
|
+
responseBody: response?.body,
|
|
122
|
+
responseMessages: response?.messages,
|
|
123
|
+
requestBody: request?.["body"],
|
|
124
|
+
requestHeaders: request?.["headers"],
|
|
125
|
+
toolCallCount: step.toolCalls?.length ?? 0,
|
|
126
|
+
toolCalls: step.toolCalls,
|
|
127
|
+
toolResults: step.toolResults,
|
|
128
|
+
errorMessage: step.finishReason === "error" ? step.text : undefined
|
|
49
129
|
}
|
|
50
130
|
};
|
|
51
131
|
await collector.collect(stepSample);
|
|
@@ -105,23 +185,60 @@ class PostHogTelemetryCollector {
|
|
|
105
185
|
}
|
|
106
186
|
async collect(sample) {
|
|
107
187
|
const client = await this.getClient();
|
|
108
|
-
const
|
|
188
|
+
const metadata = asRecord(sample.metadata);
|
|
189
|
+
const distinctId = this.config.defaults?.posthogDistinctId ?? asString(metadata["actorId"]) ?? "system";
|
|
190
|
+
const traceId = asString(metadata["traceId"]) ?? this.config.defaults?.posthogTraceId;
|
|
191
|
+
const sessionId = asString(metadata["sessionId"]);
|
|
192
|
+
const telemetryEvent = asString(metadata["telemetryEvent"]);
|
|
193
|
+
const event = telemetryEvent === "span" ? "$ai_span" : "$ai_generation";
|
|
194
|
+
const tokenUsage = metadata["tokenUsage"];
|
|
195
|
+
const totalUsage = metadata["totalUsage"];
|
|
196
|
+
const errorMessage = asString(metadata["errorMessage"]);
|
|
109
197
|
client.capture({
|
|
110
198
|
distinctId,
|
|
111
|
-
event
|
|
199
|
+
event,
|
|
112
200
|
properties: {
|
|
113
|
-
$ai_model: sample.operation.name,
|
|
114
|
-
$ai_provider: "contractspec",
|
|
201
|
+
$ai_model: asString(metadata["responseModelId"]) ?? sample.operation.name,
|
|
202
|
+
$ai_provider: asString(metadata["provider"]) ?? "contractspec",
|
|
115
203
|
$ai_latency: sample.durationMs / 1000,
|
|
116
204
|
$ai_is_error: !sample.success,
|
|
117
|
-
$
|
|
118
|
-
|
|
205
|
+
$ai_error: !sample.success ? errorMessage : undefined,
|
|
206
|
+
$ai_trace_id: traceId,
|
|
207
|
+
$ai_session_id: sessionId,
|
|
208
|
+
$ai_span_id: asString(metadata["spanId"]),
|
|
209
|
+
$ai_parent_id: asString(metadata["parentSpanId"]),
|
|
210
|
+
$ai_span_name: asString(metadata["spanName"]) ?? sample.operation.name,
|
|
211
|
+
...tokenUsage ? mapTokenUsage(tokenUsage) : {},
|
|
212
|
+
...totalUsage ? mapTotalUsage(totalUsage) : {},
|
|
213
|
+
$ai_http_status: asNumber(metadata["httpStatus"]),
|
|
214
|
+
$ai_request_url: asString(metadata["requestUrl"]),
|
|
215
|
+
$ai_base_url: asString(metadata["baseUrl"]),
|
|
119
216
|
...this.config.defaults?.posthogProperties,
|
|
120
217
|
contractspec_operation: sample.operation.name,
|
|
121
218
|
contractspec_version: sample.operation.version,
|
|
122
|
-
contractspec_agent_id:
|
|
123
|
-
|
|
124
|
-
|
|
219
|
+
contractspec_agent_id: asString(metadata["agentId"]),
|
|
220
|
+
contractspec_tenant_id: asString(metadata["tenantId"]),
|
|
221
|
+
contractspec_actor_id: asString(metadata["actorId"]),
|
|
222
|
+
contractspec_step_index: asNumber(metadata["stepIndex"]),
|
|
223
|
+
contractspec_step_started_at: asDateIso(metadata["stepStartedAt"]),
|
|
224
|
+
contractspec_finish_reason: asString(metadata["finishReason"]),
|
|
225
|
+
contractspec_finish_reason_raw: asString(metadata["rawFinishReason"]),
|
|
226
|
+
contractspec_tool_count: asNumber(metadata["toolCallCount"]),
|
|
227
|
+
contractspec_tool_name: asString(metadata["toolName"]),
|
|
228
|
+
contractspec_tool_call_args: metadata["toolCallArgs"],
|
|
229
|
+
contractspec_tool_result_output: metadata["toolResultOutput"],
|
|
230
|
+
contractspec_provider_metadata: metadata["providerMetadata"],
|
|
231
|
+
contractspec_step_warnings: metadata["warnings"],
|
|
232
|
+
contractspec_response_id: asString(metadata["responseId"]),
|
|
233
|
+
contractspec_response_model_id: asString(metadata["responseModelId"]),
|
|
234
|
+
contractspec_response_timestamp: asDateIso(metadata["responseTimestamp"]),
|
|
235
|
+
contractspec_response_headers: metadata["responseHeaders"],
|
|
236
|
+
contractspec_response_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseBody"],
|
|
237
|
+
contractspec_response_messages: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseMessages"],
|
|
238
|
+
contractspec_request_headers: metadata["requestHeaders"],
|
|
239
|
+
contractspec_request_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["requestBody"],
|
|
240
|
+
contractspec_step_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepText"],
|
|
241
|
+
contractspec_step_reasoning_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepReasoningText"]
|
|
125
242
|
},
|
|
126
243
|
groups: this.config.defaults?.posthogGroups
|
|
127
244
|
});
|
|
@@ -182,11 +299,44 @@ async function resolvePostHogClient(config) {
|
|
|
182
299
|
}
|
|
183
300
|
}
|
|
184
301
|
function mapTokenUsage(usage) {
|
|
302
|
+
const usageRecord = asRecord(usage);
|
|
303
|
+
const inputTokenDetails = asRecord(usageRecord["inputTokenDetails"]);
|
|
304
|
+
const outputTokenDetails = asRecord(usageRecord["outputTokenDetails"]);
|
|
185
305
|
return {
|
|
186
|
-
$ai_input_tokens:
|
|
187
|
-
$ai_output_tokens:
|
|
306
|
+
$ai_input_tokens: asNumber(usageRecord["inputTokens"]) ?? asNumber(usageRecord["promptTokens"]),
|
|
307
|
+
$ai_output_tokens: asNumber(usageRecord["outputTokens"]) ?? asNumber(usageRecord["completionTokens"]),
|
|
308
|
+
$ai_reasoning_tokens: asNumber(outputTokenDetails["reasoningTokens"]) ?? asNumber(usageRecord["reasoningTokens"]),
|
|
309
|
+
$ai_cache_read_input_tokens: asNumber(inputTokenDetails["cacheReadTokens"]) ?? asNumber(usageRecord["cachedInputTokens"]),
|
|
310
|
+
$ai_cache_creation_input_tokens: asNumber(inputTokenDetails["cacheWriteTokens"]),
|
|
311
|
+
$ai_usage: maybeRecord(usageRecord["raw"]) ?? usageRecord
|
|
188
312
|
};
|
|
189
313
|
}
|
|
314
|
+
function mapTotalUsage(usage) {
|
|
315
|
+
const usageRecord = asRecord(usage);
|
|
316
|
+
return {
|
|
317
|
+
contractspec_total_input_tokens: asNumber(usageRecord["inputTokens"]),
|
|
318
|
+
contractspec_total_output_tokens: asNumber(usageRecord["outputTokens"]),
|
|
319
|
+
contractspec_total_tokens: asNumber(usageRecord["totalTokens"]),
|
|
320
|
+
contractspec_total_usage_raw: maybeRecord(usageRecord["raw"]) ?? usageRecord
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function asRecord(value) {
|
|
324
|
+
return value && typeof value === "object" ? value : {};
|
|
325
|
+
}
|
|
326
|
+
function maybeRecord(value) {
|
|
327
|
+
return value && typeof value === "object" ? value : undefined;
|
|
328
|
+
}
|
|
329
|
+
function asString(value) {
|
|
330
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
331
|
+
}
|
|
332
|
+
function asNumber(value) {
|
|
333
|
+
return typeof value === "number" ? value : undefined;
|
|
334
|
+
}
|
|
335
|
+
function asDateIso(value) {
|
|
336
|
+
if (value instanceof Date)
|
|
337
|
+
return value.toISOString();
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
190
340
|
// src/telemetry/index.ts
|
|
191
341
|
init_adapter();
|
|
192
342
|
export {
|
|
@@ -15,12 +15,24 @@ export interface PostHogTracingOptions {
|
|
|
15
15
|
posthogDistinctId?: string;
|
|
16
16
|
/** Trace ID for grouping related generations */
|
|
17
17
|
posthogTraceId?: string;
|
|
18
|
+
/** Optional model id override */
|
|
19
|
+
posthogModelOverride?: string;
|
|
20
|
+
/** Optional provider override */
|
|
21
|
+
posthogProviderOverride?: string;
|
|
22
|
+
/** Optional explicit token pricing override */
|
|
23
|
+
posthogCostOverride?: PostHogCostOverride;
|
|
18
24
|
/** Custom properties attached to every generation event */
|
|
19
25
|
posthogProperties?: Record<string, unknown>;
|
|
20
26
|
/** When true, input/output content is redacted */
|
|
21
27
|
posthogPrivacyMode?: boolean;
|
|
22
28
|
/** Group analytics (e.g., { company: "companyId" }) */
|
|
23
29
|
posthogGroups?: Record<string, string>;
|
|
30
|
+
/** Sends events immediately (useful for short-lived/serverless contexts) */
|
|
31
|
+
posthogCaptureImmediate?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface PostHogCostOverride {
|
|
34
|
+
inputCost: number;
|
|
35
|
+
outputCost: number;
|
|
24
36
|
}
|
|
25
37
|
/**
|
|
26
38
|
* Minimal interface for posthog-node PostHog client.
|
|
@@ -41,23 +41,60 @@ class PostHogTelemetryCollector {
|
|
|
41
41
|
}
|
|
42
42
|
async collect(sample) {
|
|
43
43
|
const client = await this.getClient();
|
|
44
|
-
const
|
|
44
|
+
const metadata = asRecord(sample.metadata);
|
|
45
|
+
const distinctId = this.config.defaults?.posthogDistinctId ?? asString(metadata["actorId"]) ?? "system";
|
|
46
|
+
const traceId = asString(metadata["traceId"]) ?? this.config.defaults?.posthogTraceId;
|
|
47
|
+
const sessionId = asString(metadata["sessionId"]);
|
|
48
|
+
const telemetryEvent = asString(metadata["telemetryEvent"]);
|
|
49
|
+
const event = telemetryEvent === "span" ? "$ai_span" : "$ai_generation";
|
|
50
|
+
const tokenUsage = metadata["tokenUsage"];
|
|
51
|
+
const totalUsage = metadata["totalUsage"];
|
|
52
|
+
const errorMessage = asString(metadata["errorMessage"]);
|
|
45
53
|
client.capture({
|
|
46
54
|
distinctId,
|
|
47
|
-
event
|
|
55
|
+
event,
|
|
48
56
|
properties: {
|
|
49
|
-
$ai_model: sample.operation.name,
|
|
50
|
-
$ai_provider: "contractspec",
|
|
57
|
+
$ai_model: asString(metadata["responseModelId"]) ?? sample.operation.name,
|
|
58
|
+
$ai_provider: asString(metadata["provider"]) ?? "contractspec",
|
|
51
59
|
$ai_latency: sample.durationMs / 1000,
|
|
52
60
|
$ai_is_error: !sample.success,
|
|
53
|
-
$
|
|
54
|
-
|
|
61
|
+
$ai_error: !sample.success ? errorMessage : undefined,
|
|
62
|
+
$ai_trace_id: traceId,
|
|
63
|
+
$ai_session_id: sessionId,
|
|
64
|
+
$ai_span_id: asString(metadata["spanId"]),
|
|
65
|
+
$ai_parent_id: asString(metadata["parentSpanId"]),
|
|
66
|
+
$ai_span_name: asString(metadata["spanName"]) ?? sample.operation.name,
|
|
67
|
+
...tokenUsage ? mapTokenUsage(tokenUsage) : {},
|
|
68
|
+
...totalUsage ? mapTotalUsage(totalUsage) : {},
|
|
69
|
+
$ai_http_status: asNumber(metadata["httpStatus"]),
|
|
70
|
+
$ai_request_url: asString(metadata["requestUrl"]),
|
|
71
|
+
$ai_base_url: asString(metadata["baseUrl"]),
|
|
55
72
|
...this.config.defaults?.posthogProperties,
|
|
56
73
|
contractspec_operation: sample.operation.name,
|
|
57
74
|
contractspec_version: sample.operation.version,
|
|
58
|
-
contractspec_agent_id:
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
contractspec_agent_id: asString(metadata["agentId"]),
|
|
76
|
+
contractspec_tenant_id: asString(metadata["tenantId"]),
|
|
77
|
+
contractspec_actor_id: asString(metadata["actorId"]),
|
|
78
|
+
contractspec_step_index: asNumber(metadata["stepIndex"]),
|
|
79
|
+
contractspec_step_started_at: asDateIso(metadata["stepStartedAt"]),
|
|
80
|
+
contractspec_finish_reason: asString(metadata["finishReason"]),
|
|
81
|
+
contractspec_finish_reason_raw: asString(metadata["rawFinishReason"]),
|
|
82
|
+
contractspec_tool_count: asNumber(metadata["toolCallCount"]),
|
|
83
|
+
contractspec_tool_name: asString(metadata["toolName"]),
|
|
84
|
+
contractspec_tool_call_args: metadata["toolCallArgs"],
|
|
85
|
+
contractspec_tool_result_output: metadata["toolResultOutput"],
|
|
86
|
+
contractspec_provider_metadata: metadata["providerMetadata"],
|
|
87
|
+
contractspec_step_warnings: metadata["warnings"],
|
|
88
|
+
contractspec_response_id: asString(metadata["responseId"]),
|
|
89
|
+
contractspec_response_model_id: asString(metadata["responseModelId"]),
|
|
90
|
+
contractspec_response_timestamp: asDateIso(metadata["responseTimestamp"]),
|
|
91
|
+
contractspec_response_headers: metadata["responseHeaders"],
|
|
92
|
+
contractspec_response_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseBody"],
|
|
93
|
+
contractspec_response_messages: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseMessages"],
|
|
94
|
+
contractspec_request_headers: metadata["requestHeaders"],
|
|
95
|
+
contractspec_request_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["requestBody"],
|
|
96
|
+
contractspec_step_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepText"],
|
|
97
|
+
contractspec_step_reasoning_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepReasoningText"]
|
|
61
98
|
},
|
|
62
99
|
groups: this.config.defaults?.posthogGroups
|
|
63
100
|
});
|
|
@@ -118,11 +155,44 @@ async function resolvePostHogClient(config) {
|
|
|
118
155
|
}
|
|
119
156
|
}
|
|
120
157
|
function mapTokenUsage(usage) {
|
|
158
|
+
const usageRecord = asRecord(usage);
|
|
159
|
+
const inputTokenDetails = asRecord(usageRecord["inputTokenDetails"]);
|
|
160
|
+
const outputTokenDetails = asRecord(usageRecord["outputTokenDetails"]);
|
|
121
161
|
return {
|
|
122
|
-
$ai_input_tokens:
|
|
123
|
-
$ai_output_tokens:
|
|
162
|
+
$ai_input_tokens: asNumber(usageRecord["inputTokens"]) ?? asNumber(usageRecord["promptTokens"]),
|
|
163
|
+
$ai_output_tokens: asNumber(usageRecord["outputTokens"]) ?? asNumber(usageRecord["completionTokens"]),
|
|
164
|
+
$ai_reasoning_tokens: asNumber(outputTokenDetails["reasoningTokens"]) ?? asNumber(usageRecord["reasoningTokens"]),
|
|
165
|
+
$ai_cache_read_input_tokens: asNumber(inputTokenDetails["cacheReadTokens"]) ?? asNumber(usageRecord["cachedInputTokens"]),
|
|
166
|
+
$ai_cache_creation_input_tokens: asNumber(inputTokenDetails["cacheWriteTokens"]),
|
|
167
|
+
$ai_usage: maybeRecord(usageRecord["raw"]) ?? usageRecord
|
|
124
168
|
};
|
|
125
169
|
}
|
|
170
|
+
function mapTotalUsage(usage) {
|
|
171
|
+
const usageRecord = asRecord(usage);
|
|
172
|
+
return {
|
|
173
|
+
contractspec_total_input_tokens: asNumber(usageRecord["inputTokens"]),
|
|
174
|
+
contractspec_total_output_tokens: asNumber(usageRecord["outputTokens"]),
|
|
175
|
+
contractspec_total_tokens: asNumber(usageRecord["totalTokens"]),
|
|
176
|
+
contractspec_total_usage_raw: maybeRecord(usageRecord["raw"]) ?? usageRecord
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function asRecord(value) {
|
|
180
|
+
return value && typeof value === "object" ? value : {};
|
|
181
|
+
}
|
|
182
|
+
function maybeRecord(value) {
|
|
183
|
+
return value && typeof value === "object" ? value : undefined;
|
|
184
|
+
}
|
|
185
|
+
function asString(value) {
|
|
186
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
187
|
+
}
|
|
188
|
+
function asNumber(value) {
|
|
189
|
+
return typeof value === "number" ? value : undefined;
|
|
190
|
+
}
|
|
191
|
+
function asDateIso(value) {
|
|
192
|
+
if (value instanceof Date)
|
|
193
|
+
return value.toISOString();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
126
196
|
export {
|
|
127
197
|
createPostHogTracedModel,
|
|
128
198
|
createPostHogTelemetryCollector,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/lib.ai-agent",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "AI agent orchestration with MCP and tool support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
43
43
|
"@posthog/react": "^1.7.1",
|
|
44
44
|
"@posthog/ai": "latest",
|
|
45
|
-
"@contractspec/lib.contracts-spec": "2.
|
|
46
|
-
"@contractspec/lib.ai-providers": "2.
|
|
47
|
-
"@contractspec/lib.knowledge": "2.
|
|
45
|
+
"@contractspec/lib.contracts-spec": "2.1.1",
|
|
46
|
+
"@contractspec/lib.ai-providers": "2.1.0",
|
|
47
|
+
"@contractspec/lib.knowledge": "2.1.1",
|
|
48
48
|
"compare-versions": "^6.1.1",
|
|
49
49
|
"zod": "^4.3.5"
|
|
50
50
|
},
|
|
@@ -68,9 +68,9 @@
|
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@contractspec/tool.typescript": "2.
|
|
71
|
+
"@contractspec/tool.typescript": "2.1.0",
|
|
72
72
|
"typescript": "^5.9.3",
|
|
73
|
-
"@contractspec/tool.bun": "2.
|
|
73
|
+
"@contractspec/tool.bun": "2.1.0"
|
|
74
74
|
},
|
|
75
75
|
"exports": {
|
|
76
76
|
".": {
|