@opengeni/observability 1.4.4 → 1.4.5-canary.37458084490001
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-tool-metrics.d.ts +25 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +234 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/agent-tool-metrics.ts +193 -0
- package/src/index.ts +99 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Observability } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Closed, low-cardinality families for agent tool calls. A tool's exact name,
|
|
4
|
+
* MCP server, connector domain, arguments, and output never become labels;
|
|
5
|
+
* unknown future tools collapse to `other` until reviewed here.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AGENT_TOOL_METRIC_FAMILIES: readonly ["shell", "apply_patch", "browser", "computer", "human_handoff", "human_input", "image", "video", "web", "memory", "goal", "session", "machine", "skill", "tool_router", "files", "connector", "integration", "custom_mcp", "codemode", "other"];
|
|
8
|
+
export type AgentToolMetricFamily = (typeof AGENT_TOOL_METRIC_FAMILIES)[number];
|
|
9
|
+
export declare const AGENT_TOOL_CALL_OUTCOMES: readonly ["ok", "error", "rejected", "cancelled"];
|
|
10
|
+
export type AgentToolCallOutcome = (typeof AGENT_TOOL_CALL_OUTCOMES)[number];
|
|
11
|
+
/**
|
|
12
|
+
* Map the content-free analytics family computed for a tool call
|
|
13
|
+
* (`toolCallFamily`: a first-party tool name, `integration:<domain>`, or
|
|
14
|
+
* `custom`) — or, when absent, the model-facing tool name — onto the closed
|
|
15
|
+
* metric family set.
|
|
16
|
+
*/
|
|
17
|
+
export declare function agentToolMetricFamily(toolFamily: string | null | undefined, name?: string | null): AgentToolMetricFamily;
|
|
18
|
+
/** Structural outcome of a normalized `agent.toolCall.output` payload. */
|
|
19
|
+
export declare function agentToolCallOutcome(payload: unknown): AgentToolCallOutcome;
|
|
20
|
+
/** Count one completed agent tool call. Telemetry failures never reach the turn. */
|
|
21
|
+
export declare function recordAgentToolCall(observability: Observability | null | undefined, input: {
|
|
22
|
+
family: AgentToolMetricFamily;
|
|
23
|
+
outcome: AgentToolCallOutcome;
|
|
24
|
+
durationMs?: number;
|
|
25
|
+
}): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type TraceContext } from "./trace-context.js";
|
|
2
2
|
import { type FailureDiagnosticInput } from "./failure-diagnostic.js";
|
|
3
3
|
export type { FailureDiagnosticInput } from "./failure-diagnostic.js";
|
|
4
|
+
export { AGENT_TOOL_CALL_OUTCOMES, AGENT_TOOL_METRIC_FAMILIES, agentToolCallOutcome, agentToolMetricFamily, recordAgentToolCall, type AgentToolCallOutcome, type AgentToolMetricFamily, } from "./agent-tool-metrics.js";
|
|
4
5
|
export { failureDiagnostic } from "./failure-diagnostic.js";
|
|
5
6
|
export { createLogThrottle, type LogThrottle } from "./log-throttle.js";
|
|
6
7
|
export { withMcpTelemetry, withMcpCallIdentity, bindMcpTelemetry, beginMcpPhase, measureMcpPhase, recordToolApproval, MCP_EXECUTION_PHASES, } from "./mcp-timing.js";
|
|
@@ -150,6 +151,19 @@ export declare class Observability {
|
|
|
150
151
|
status: number;
|
|
151
152
|
durationSeconds: number;
|
|
152
153
|
}): void;
|
|
154
|
+
/**
|
|
155
|
+
* Count a rejected API request by route, status, public error code, and a
|
|
156
|
+
* bounded reason (`permission:<name>`, a typed detail code, or
|
|
157
|
+
* `unclassified`). Values outside the closed grammars collapse to `other` so
|
|
158
|
+
* a malformed caller can never mint a free-form series.
|
|
159
|
+
*/
|
|
160
|
+
recordHttpRejection(input: {
|
|
161
|
+
method: string;
|
|
162
|
+
route: string;
|
|
163
|
+
status: number;
|
|
164
|
+
code: string;
|
|
165
|
+
reason: string;
|
|
166
|
+
}): void;
|
|
153
167
|
recordWorkerActivity(input: {
|
|
154
168
|
activity: string;
|
|
155
169
|
status: string;
|
|
@@ -220,6 +234,8 @@ export type InteractionOperationMetricObservation = {
|
|
|
220
234
|
operation: string;
|
|
221
235
|
outcome: string;
|
|
222
236
|
mode: string;
|
|
237
|
+
/** Bounded failure reason; `none` for successful or non-failed outcomes. */
|
|
238
|
+
reason?: string | undefined;
|
|
223
239
|
durationMs: number;
|
|
224
240
|
replayed?: boolean | undefined;
|
|
225
241
|
};
|
package/dist/index.js
CHANGED
|
@@ -291,6 +291,157 @@ function failureDiagnostic(input, revision) {
|
|
|
291
291
|
};
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
// src/agent-tool-metrics.ts
|
|
295
|
+
var AGENT_TOOL_METRIC_FAMILIES = [
|
|
296
|
+
"shell",
|
|
297
|
+
"apply_patch",
|
|
298
|
+
"browser",
|
|
299
|
+
"computer",
|
|
300
|
+
"human_handoff",
|
|
301
|
+
"human_input",
|
|
302
|
+
"image",
|
|
303
|
+
"video",
|
|
304
|
+
"web",
|
|
305
|
+
"memory",
|
|
306
|
+
"goal",
|
|
307
|
+
"session",
|
|
308
|
+
"machine",
|
|
309
|
+
"skill",
|
|
310
|
+
"tool_router",
|
|
311
|
+
"files",
|
|
312
|
+
"connector",
|
|
313
|
+
"integration",
|
|
314
|
+
"custom_mcp",
|
|
315
|
+
"codemode",
|
|
316
|
+
"other"
|
|
317
|
+
];
|
|
318
|
+
var AGENT_TOOL_CALL_OUTCOMES = ["ok", "error", "rejected", "cancelled"];
|
|
319
|
+
var EXACT = {
|
|
320
|
+
exec_command: "shell",
|
|
321
|
+
write_stdin: "shell",
|
|
322
|
+
local_shell_call: "shell",
|
|
323
|
+
shell_call: "shell",
|
|
324
|
+
shell: "shell",
|
|
325
|
+
command_wait: "shell",
|
|
326
|
+
command_read: "shell",
|
|
327
|
+
interaction_discover: "browser",
|
|
328
|
+
interaction_request_human: "human_handoff",
|
|
329
|
+
request_human_input: "human_input",
|
|
330
|
+
wait_for_input: "human_input",
|
|
331
|
+
session_human_input_respond: "human_input",
|
|
332
|
+
generate_image: "image",
|
|
333
|
+
view_image: "image",
|
|
334
|
+
image_generation_call: "image",
|
|
335
|
+
generate_video: "video",
|
|
336
|
+
get_video_generation_capabilities: "video",
|
|
337
|
+
web_fetch: "web",
|
|
338
|
+
set_session_title: "session",
|
|
339
|
+
notify_user: "session",
|
|
340
|
+
set_other_session_title: "session",
|
|
341
|
+
sessions_list: "session",
|
|
342
|
+
sandboxes_list: "machine",
|
|
343
|
+
sandbox_attach: "machine",
|
|
344
|
+
sandbox_swap: "machine",
|
|
345
|
+
sandbox_provision: "machine",
|
|
346
|
+
run_on: "machine",
|
|
347
|
+
load_skill: "skill",
|
|
348
|
+
repository_skill_read: "skill",
|
|
349
|
+
tool_search: "tool_router",
|
|
350
|
+
tool_list: "tool_router",
|
|
351
|
+
tool_invoke: "tool_router",
|
|
352
|
+
sandbox_file_publish: "files",
|
|
353
|
+
google_drive_publish_file: "files",
|
|
354
|
+
custom_mcp_setup_request: "connector",
|
|
355
|
+
list_models: "other"
|
|
356
|
+
};
|
|
357
|
+
var PREFIXES = [
|
|
358
|
+
["apply_patch", "apply_patch"],
|
|
359
|
+
["browser_", "browser"],
|
|
360
|
+
["computer_", "computer"],
|
|
361
|
+
["web_search", "web"],
|
|
362
|
+
["knowledge_", "memory"],
|
|
363
|
+
["memory_", "memory"],
|
|
364
|
+
["instruction_policy_", "memory"],
|
|
365
|
+
["preference_", "memory"],
|
|
366
|
+
["task_note", "memory"],
|
|
367
|
+
["remember", "memory"],
|
|
368
|
+
["company_profile_", "memory"],
|
|
369
|
+
["work_claim_", "memory"],
|
|
370
|
+
["goal_", "goal"],
|
|
371
|
+
["session_", "session"],
|
|
372
|
+
["project_", "session"],
|
|
373
|
+
["rig_", "session"],
|
|
374
|
+
["scheduled_task", "session"],
|
|
375
|
+
["connected_machine_", "machine"],
|
|
376
|
+
["skill_", "skill"],
|
|
377
|
+
["artifacts_", "files"],
|
|
378
|
+
["editable_artifact_", "files"],
|
|
379
|
+
["files_", "files"],
|
|
380
|
+
["slack_", "connector"],
|
|
381
|
+
["fiken_", "connector"],
|
|
382
|
+
["x_", "connector"],
|
|
383
|
+
["reddit_", "connector"],
|
|
384
|
+
["social_", "connector"],
|
|
385
|
+
["github_", "connector"],
|
|
386
|
+
["atlassian_", "connector"],
|
|
387
|
+
["gmail_", "connector"],
|
|
388
|
+
["variable_set_", "connector"],
|
|
389
|
+
["environment_", "connector"],
|
|
390
|
+
["capability_", "connector"]
|
|
391
|
+
];
|
|
392
|
+
function agentToolMetricFamily(toolFamily, name) {
|
|
393
|
+
if (toolFamily === "custom") return "custom_mcp";
|
|
394
|
+
if (toolFamily?.startsWith("integration:")) return "integration";
|
|
395
|
+
const candidate = (toolFamily ?? name ?? "").replace(/^(?:opengeni|interaction)__/, "").toLowerCase();
|
|
396
|
+
if (!candidate) return "other";
|
|
397
|
+
const exact = EXACT[candidate];
|
|
398
|
+
if (exact) return exact;
|
|
399
|
+
for (const [prefix, family] of PREFIXES) {
|
|
400
|
+
if (candidate.startsWith(prefix)) return family;
|
|
401
|
+
}
|
|
402
|
+
return "other";
|
|
403
|
+
}
|
|
404
|
+
var SDK_NOT_APPROVED = "Tool execution was not approved.";
|
|
405
|
+
var SDK_TOOL_ERROR_PREFIX = "An error occurred while running the tool";
|
|
406
|
+
function agentToolCallOutcome(payload) {
|
|
407
|
+
if (!payload || typeof payload !== "object") return "ok";
|
|
408
|
+
const record = payload;
|
|
409
|
+
if (record.error === true || record.failed === true) return "error";
|
|
410
|
+
const output = record.output;
|
|
411
|
+
if (output && typeof output === "object" && output.isError === true) {
|
|
412
|
+
return "error";
|
|
413
|
+
}
|
|
414
|
+
const text = typeof output === "string" ? output : output && typeof output === "object" && typeof output.text === "string" ? output.text : null;
|
|
415
|
+
if (text !== null) {
|
|
416
|
+
const trimmed = text.trim();
|
|
417
|
+
if (trimmed === SDK_NOT_APPROVED) return "rejected";
|
|
418
|
+
if (trimmed === "aborted") return "cancelled";
|
|
419
|
+
if (trimmed.startsWith(SDK_TOOL_ERROR_PREFIX)) return "error";
|
|
420
|
+
}
|
|
421
|
+
return "ok";
|
|
422
|
+
}
|
|
423
|
+
function recordAgentToolCall(observability, input) {
|
|
424
|
+
if (!observability) return;
|
|
425
|
+
const family = AGENT_TOOL_METRIC_FAMILIES.includes(input.family) ? input.family : "other";
|
|
426
|
+
const outcome = AGENT_TOOL_CALL_OUTCOMES.includes(input.outcome) ? input.outcome : "ok";
|
|
427
|
+
try {
|
|
428
|
+
observability.incrementCounter({
|
|
429
|
+
name: "opengeni_agent_tool_calls_total",
|
|
430
|
+
help: "Completed agent tool calls by closed tool family and structural outcome.",
|
|
431
|
+
labels: { family, outcome }
|
|
432
|
+
});
|
|
433
|
+
if (input.durationMs !== void 0 && Number.isFinite(input.durationMs)) {
|
|
434
|
+
observability.observeHistogram({
|
|
435
|
+
name: "opengeni_agent_tool_call_duration_seconds",
|
|
436
|
+
help: "Agent tool-call duration in seconds by closed tool family.",
|
|
437
|
+
labels: { family },
|
|
438
|
+
value: Math.max(0, input.durationMs) / 1e3
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
} catch {
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
294
445
|
// src/log-throttle.ts
|
|
295
446
|
function createLogThrottle(options) {
|
|
296
447
|
const intervalMs = Math.max(0, options.intervalMs);
|
|
@@ -553,10 +704,57 @@ var INTERACTION_OUTCOMES = /* @__PURE__ */ new Set([
|
|
|
553
704
|
"dispatched",
|
|
554
705
|
"completed",
|
|
555
706
|
"failed",
|
|
707
|
+
"denied",
|
|
556
708
|
"outcome_unknown",
|
|
557
709
|
"stale",
|
|
558
710
|
"cancelled"
|
|
559
711
|
]);
|
|
712
|
+
var INTERACTION_OPERATION_REASONS = /* @__PURE__ */ new Set([
|
|
713
|
+
"none",
|
|
714
|
+
"resource_not_found",
|
|
715
|
+
"resource_unavailable",
|
|
716
|
+
"controller_stale",
|
|
717
|
+
"target_not_found",
|
|
718
|
+
"target_stale",
|
|
719
|
+
"observation_stale",
|
|
720
|
+
"document_stale",
|
|
721
|
+
"frame_stale",
|
|
722
|
+
"locator_not_found",
|
|
723
|
+
"locator_ambiguous",
|
|
724
|
+
"unsupported",
|
|
725
|
+
"permission_denied",
|
|
726
|
+
"machine_locked",
|
|
727
|
+
"attempt_stale",
|
|
728
|
+
"operation_conflict",
|
|
729
|
+
"outcome_unknown",
|
|
730
|
+
"invalid_action",
|
|
731
|
+
"timeout",
|
|
732
|
+
"controller_lost",
|
|
733
|
+
"driver_failed",
|
|
734
|
+
"action_failed",
|
|
735
|
+
"stale",
|
|
736
|
+
"unauthenticated",
|
|
737
|
+
"access_denied",
|
|
738
|
+
"not_found",
|
|
739
|
+
"conflict",
|
|
740
|
+
"invalid_request",
|
|
741
|
+
"rate_limited",
|
|
742
|
+
"unavailable",
|
|
743
|
+
"internal",
|
|
744
|
+
"rejected",
|
|
745
|
+
"control_unsupported",
|
|
746
|
+
"control_os",
|
|
747
|
+
"control_not_found",
|
|
748
|
+
"control_consent_required",
|
|
749
|
+
"control_timeout",
|
|
750
|
+
"control_draining",
|
|
751
|
+
"control_protocol",
|
|
752
|
+
"control_stream",
|
|
753
|
+
"control_agent_offline",
|
|
754
|
+
"control_fenced",
|
|
755
|
+
"control_payload_too_large",
|
|
756
|
+
"control_unknown"
|
|
757
|
+
]);
|
|
560
758
|
var INTERACTION_MODES = /* @__PURE__ */ new Set([
|
|
561
759
|
"semantic",
|
|
562
760
|
"coordinate",
|
|
@@ -649,10 +847,18 @@ var PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
|
|
|
649
847
|
"retainedOutputKind",
|
|
650
848
|
"suppressedCount"
|
|
651
849
|
]);
|
|
850
|
+
var HTTP_REJECTION_CODE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
|
|
851
|
+
var HTTP_REJECTION_REASON_PATTERN = /^(?:permission:[a-z][a-z0-9-]*:[a-z][a-z0-9-]*|control:[a-z][a-z0-9_]{0,31}|[A-Za-z][A-Za-z0-9_.-]{0,63})$/;
|
|
652
852
|
var PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS = /* @__PURE__ */ new Map([
|
|
653
853
|
["mcpCallKey", /^mcp_[0-9a-f]{32}$/],
|
|
654
854
|
["sandboxLeaseKey", /^slk_[0-9a-f]{32}$/],
|
|
655
855
|
["correlationId", /^[A-Za-z0-9._:-]{1,128}$/],
|
|
856
|
+
// Rejected-request classification (apps/api/src/http/rejection-telemetry.ts):
|
|
857
|
+
// the public ErrorEnvelope code enum, a catalog permission or typed detail
|
|
858
|
+
// code, and a one-way message hash. Never message text or identifiers.
|
|
859
|
+
["rejectionCode", HTTP_REJECTION_CODE_PATTERN],
|
|
860
|
+
["rejectionReason", HTTP_REJECTION_REASON_PATTERN],
|
|
861
|
+
["rejectionFingerprint", /^m_[0-9a-f]{10}$/],
|
|
656
862
|
// Web error beacon: a route PATTERN of lowercase literal and `$param`
|
|
657
863
|
// segments (never a concrete path or id) and the bundle revision token, in
|
|
658
864
|
// the exact wire grammar the API route admits.
|
|
@@ -1073,6 +1279,26 @@ var Observability = class {
|
|
|
1073
1279
|
}
|
|
1074
1280
|
});
|
|
1075
1281
|
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Count a rejected API request by route, status, public error code, and a
|
|
1284
|
+
* bounded reason (`permission:<name>`, a typed detail code, or
|
|
1285
|
+
* `unclassified`). Values outside the closed grammars collapse to `other` so
|
|
1286
|
+
* a malformed caller can never mint a free-form series.
|
|
1287
|
+
*/
|
|
1288
|
+
recordHttpRejection(input) {
|
|
1289
|
+
this.incrementCounter({
|
|
1290
|
+
name: "opengeni_http_request_rejections_total",
|
|
1291
|
+
help: "Rejected HTTP requests (status >= 400) by route, status, public error code, and bounded reason.",
|
|
1292
|
+
labels: {
|
|
1293
|
+
method: input.method,
|
|
1294
|
+
route: input.route,
|
|
1295
|
+
status: String(input.status),
|
|
1296
|
+
code: HTTP_REJECTION_CODE_PATTERN.test(input.code) ? input.code : "other",
|
|
1297
|
+
reason: HTTP_REJECTION_REASON_PATTERN.test(input.reason) ? input.reason : "other",
|
|
1298
|
+
component: this.options.component
|
|
1299
|
+
}
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1076
1302
|
recordWorkerActivity(input) {
|
|
1077
1303
|
this.incrementCounter({
|
|
1078
1304
|
name: "opengeni_worker_activity_runs_total",
|
|
@@ -1381,11 +1607,12 @@ function interactionOperationMetricObserver(observability) {
|
|
|
1381
1607
|
const operation = boundedMetricEnum(INTERACTION_OPERATIONS, observation.operation);
|
|
1382
1608
|
const outcome = boundedMetricEnum(INTERACTION_OUTCOMES, observation.outcome);
|
|
1383
1609
|
const mode = boundedMetricEnum(INTERACTION_MODES, observation.mode);
|
|
1610
|
+
const reason = boundedMetricEnum(INTERACTION_OPERATION_REASONS, observation.reason ?? "none");
|
|
1384
1611
|
try {
|
|
1385
1612
|
observability.incrementCounter({
|
|
1386
1613
|
name: "opengeni_interaction_operations_total",
|
|
1387
|
-
help: "Browser and Computer operations by bounded resource, operation, mode, and
|
|
1388
|
-
labels: { resource, operation, mode, outcome }
|
|
1614
|
+
help: "Browser and Computer operations by bounded resource, operation, mode, outcome, and failure reason.",
|
|
1615
|
+
labels: { resource, operation, mode, outcome, reason }
|
|
1389
1616
|
});
|
|
1390
1617
|
observability.observeHistogram({
|
|
1391
1618
|
name: "opengeni_interaction_operation_duration_seconds",
|
|
@@ -1810,11 +2037,15 @@ async function defaultExporter(url, body, headers) {
|
|
|
1810
2037
|
}
|
|
1811
2038
|
}
|
|
1812
2039
|
export {
|
|
2040
|
+
AGENT_TOOL_CALL_OUTCOMES,
|
|
2041
|
+
AGENT_TOOL_METRIC_FAMILIES,
|
|
1813
2042
|
MCP_EXECUTION_PHASES,
|
|
1814
2043
|
OPENGENI_OBSERVABILITY_DISTRIBUTION,
|
|
1815
2044
|
Observability,
|
|
1816
2045
|
TENANCY_COMPATIBILITY_LANES,
|
|
1817
2046
|
admissionTraceContext,
|
|
2047
|
+
agentToolCallOutcome,
|
|
2048
|
+
agentToolMetricFamily,
|
|
1818
2049
|
beginMcpPhase,
|
|
1819
2050
|
bindMcpTelemetry,
|
|
1820
2051
|
createLogThrottle,
|
|
@@ -1829,6 +2060,7 @@ export {
|
|
|
1829
2060
|
measureMcpPhase,
|
|
1830
2061
|
parseHeaders,
|
|
1831
2062
|
parseTraceparent,
|
|
2063
|
+
recordAgentToolCall,
|
|
1832
2064
|
recordTenancyCompatibilityLaneUse,
|
|
1833
2065
|
recordToolApproval,
|
|
1834
2066
|
recordWorkflowWakeReconciliation,
|