@mongodb-js/agent-engine-runner-shared 0.11.3
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/CHANGELOG.md +55 -0
- package/LICENSE.md +201 -0
- package/README.md +29 -0
- package/dist/agent_config.d.ts +167 -0
- package/dist/agent_config.d.ts.map +1 -0
- package/dist/agent_config.js +544 -0
- package/dist/call_interrupted.d.ts +12 -0
- package/dist/call_interrupted.d.ts.map +1 -0
- package/dist/call_interrupted.js +11 -0
- package/dist/checkpoint_workspace.d.ts +25 -0
- package/dist/checkpoint_workspace.d.ts.map +1 -0
- package/dist/checkpoint_workspace.js +44 -0
- package/dist/context.d.ts +235 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +322 -0
- package/dist/db_config.d.ts +28 -0
- package/dist/db_config.d.ts.map +1 -0
- package/dist/db_config.js +66 -0
- package/dist/db_naming.d.ts +54 -0
- package/dist/db_naming.d.ts.map +1 -0
- package/dist/db_naming.js +94 -0
- package/dist/error_reporting.d.ts +67 -0
- package/dist/error_reporting.d.ts.map +1 -0
- package/dist/error_reporting.js +311 -0
- package/dist/generated/workflow/v1/activity_pb.d.ts +342 -0
- package/dist/generated/workflow/v1/activity_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/activity_pb.js +115 -0
- package/dist/generated/workflow/v1/common_pb.d.ts +184 -0
- package/dist/generated/workflow/v1/common_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/common_pb.js +86 -0
- package/dist/generated/workflow/v1/runtime_pb.d.ts +200 -0
- package/dist/generated/workflow/v1/runtime_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/runtime_pb.js +40 -0
- package/dist/generated/workflow/v1/state_pb.d.ts +254 -0
- package/dist/generated/workflow/v1/state_pb.d.ts.map +1 -0
- package/dist/generated/workflow/v1/state_pb.js +68 -0
- package/dist/guardrails_evaluator/core.d.ts +23 -0
- package/dist/guardrails_evaluator/core.d.ts.map +1 -0
- package/dist/guardrails_evaluator/core.js +122 -0
- package/dist/guardrails_evaluator/index.d.ts +10 -0
- package/dist/guardrails_evaluator/index.d.ts.map +1 -0
- package/dist/guardrails_evaluator/index.js +11 -0
- package/dist/guardrails_evaluator/regex.d.ts +20 -0
- package/dist/guardrails_evaluator/regex.d.ts.map +1 -0
- package/dist/guardrails_evaluator/regex.js +233 -0
- package/dist/hooks.d.ts +109 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +216 -0
- package/dist/http_path.d.ts +18 -0
- package/dist/http_path.d.ts.map +1 -0
- package/dist/http_path.js +53 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/launcher.d.ts +130 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +325 -0
- package/dist/logger.d.ts +96 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +204 -0
- package/dist/mcp_oauth.d.ts +51 -0
- package/dist/mcp_oauth.d.ts.map +1 -0
- package/dist/mcp_oauth.js +389 -0
- package/dist/mcp_oauth_secret.d.ts +21 -0
- package/dist/mcp_oauth_secret.d.ts.map +1 -0
- package/dist/mcp_oauth_secret.js +122 -0
- package/dist/mcp_tools.d.ts +71 -0
- package/dist/mcp_tools.d.ts.map +1 -0
- package/dist/mcp_tools.js +301 -0
- package/dist/memory_appbound.d.ts +42 -0
- package/dist/memory_appbound.d.ts.map +1 -0
- package/dist/memory_appbound.js +159 -0
- package/dist/memory_writer.d.ts +49 -0
- package/dist/memory_writer.d.ts.map +1 -0
- package/dist/memory_writer.js +171 -0
- package/dist/metrics.d.ts +84 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +205 -0
- package/dist/models.d.ts +1458 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +1726 -0
- package/dist/node_logger.d.ts +43 -0
- package/dist/node_logger.d.ts.map +1 -0
- package/dist/node_logger.js +158 -0
- package/dist/owner_callback.d.ts +16 -0
- package/dist/owner_callback.d.ts.map +1 -0
- package/dist/owner_callback.js +40 -0
- package/dist/progress.d.ts +57 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +140 -0
- package/dist/runtime.d.ts +131 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +351 -0
- package/dist/secure_llm_proxy.d.ts +115 -0
- package/dist/secure_llm_proxy.d.ts.map +1 -0
- package/dist/secure_llm_proxy.js +922 -0
- package/dist/secure_wrapper.d.ts +332 -0
- package/dist/secure_wrapper.d.ts.map +1 -0
- package/dist/secure_wrapper.js +1249 -0
- package/dist/server/aer.d.ts +61 -0
- package/dist/server/aer.d.ts.map +1 -0
- package/dist/server/aer.js +1124 -0
- package/dist/server/auth.d.ts +56 -0
- package/dist/server/auth.d.ts.map +1 -0
- package/dist/server/auth.js +132 -0
- package/dist/server/base.d.ts +104 -0
- package/dist/server/base.d.ts.map +1 -0
- package/dist/server/base.js +150 -0
- package/dist/server/callInterrupt.d.ts +49 -0
- package/dist/server/callInterrupt.d.ts.map +1 -0
- package/dist/server/callInterrupt.js +68 -0
- package/dist/server/callback_delivery.d.ts +14 -0
- package/dist/server/callback_delivery.d.ts.map +1 -0
- package/dist/server/callback_delivery.js +141 -0
- package/dist/server/chunk_types.d.ts +50 -0
- package/dist/server/chunk_types.d.ts.map +1 -0
- package/dist/server/chunk_types.js +62 -0
- package/dist/server/cors.d.ts +52 -0
- package/dist/server/cors.d.ts.map +1 -0
- package/dist/server/cors.js +107 -0
- package/dist/server/drain.d.ts +169 -0
- package/dist/server/drain.d.ts.map +1 -0
- package/dist/server/drain.js +455 -0
- package/dist/server/function.d.ts +77 -0
- package/dist/server/function.d.ts.map +1 -0
- package/dist/server/function.js +337 -0
- package/dist/server/http_retry.d.ts +37 -0
- package/dist/server/http_retry.d.ts.map +1 -0
- package/dist/server/http_retry.js +157 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +5 -0
- package/dist/server/metadata.d.ts +50 -0
- package/dist/server/metadata.d.ts.map +1 -0
- package/dist/server/metadata.js +193 -0
- package/dist/server/oe_url.d.ts +36 -0
- package/dist/server/oe_url.d.ts.map +1 -0
- package/dist/server/oe_url.js +50 -0
- package/dist/server/owner_url.d.ts +35 -0
- package/dist/server/owner_url.d.ts.map +1 -0
- package/dist/server/owner_url.js +146 -0
- package/dist/server/query.d.ts +42 -0
- package/dist/server/query.d.ts.map +1 -0
- package/dist/server/query.js +28 -0
- package/dist/server/tool.d.ts +138 -0
- package/dist/server/tool.d.ts.map +1 -0
- package/dist/server/tool.js +1017 -0
- package/dist/span_names.d.ts +21 -0
- package/dist/span_names.d.ts.map +1 -0
- package/dist/span_names.js +31 -0
- package/dist/structured_logging/constants.d.ts +17 -0
- package/dist/structured_logging/constants.d.ts.map +1 -0
- package/dist/structured_logging/constants.js +71 -0
- package/dist/structured_logging/env.d.ts +18 -0
- package/dist/structured_logging/env.d.ts.map +1 -0
- package/dist/structured_logging/env.js +39 -0
- package/dist/structured_logging/install.d.ts +56 -0
- package/dist/structured_logging/install.d.ts.map +1 -0
- package/dist/structured_logging/install.js +107 -0
- package/dist/structured_logging/layout.d.ts +9 -0
- package/dist/structured_logging/layout.d.ts.map +1 -0
- package/dist/structured_logging/layout.js +144 -0
- package/dist/structured_logging/serialize.d.ts +27 -0
- package/dist/structured_logging/serialize.d.ts.map +1 -0
- package/dist/structured_logging/serialize.js +61 -0
- package/dist/structured_logging/stdio_capture.d.ts +59 -0
- package/dist/structured_logging/stdio_capture.d.ts.map +1 -0
- package/dist/structured_logging/stdio_capture.js +164 -0
- package/dist/structured_logging/uncaught.d.ts +14 -0
- package/dist/structured_logging/uncaught.d.ts.map +1 -0
- package/dist/structured_logging/uncaught.js +58 -0
- package/dist/structured_logging.d.ts +48 -0
- package/dist/structured_logging.d.ts.map +1 -0
- package/dist/structured_logging.js +47 -0
- package/dist/tls_client.d.ts +61 -0
- package/dist/tls_client.d.ts.map +1 -0
- package/dist/tls_client.js +298 -0
- package/dist/tool_api_error.d.ts +62 -0
- package/dist/tool_api_error.d.ts.map +1 -0
- package/dist/tool_api_error.js +399 -0
- package/dist/tool_memory_ownership.d.ts +10 -0
- package/dist/tool_memory_ownership.d.ts.map +1 -0
- package/dist/tool_memory_ownership.js +36 -0
- package/dist/toolpod_handlers.d.ts +126 -0
- package/dist/toolpod_handlers.d.ts.map +1 -0
- package/dist/toolpod_handlers.js +1016 -0
- package/dist/tracing/exporters.d.ts +51 -0
- package/dist/tracing/exporters.d.ts.map +1 -0
- package/dist/tracing/exporters.js +327 -0
- package/dist/tracing/index.d.ts +3 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +2 -0
- package/dist/tracing/setup.d.ts +76 -0
- package/dist/tracing/setup.d.ts.map +1 -0
- package/dist/tracing/setup.js +436 -0
- package/dist/utils.d.ts +204 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +867 -0
- package/dist/workflow/activity.d.ts +71 -0
- package/dist/workflow/activity.d.ts.map +1 -0
- package/dist/workflow/activity.js +357 -0
- package/dist/workflow/attempt.d.ts +12 -0
- package/dist/workflow/attempt.d.ts.map +1 -0
- package/dist/workflow/attempt.js +96 -0
- package/dist/workflow/client.d.ts +46 -0
- package/dist/workflow/client.d.ts.map +1 -0
- package/dist/workflow/client.js +299 -0
- package/dist/workflow/context.d.ts +37 -0
- package/dist/workflow/context.d.ts.map +1 -0
- package/dist/workflow/context.js +350 -0
- package/dist/workflow/heartbeat.d.ts +15 -0
- package/dist/workflow/heartbeat.d.ts.map +1 -0
- package/dist/workflow/heartbeat.js +78 -0
- package/dist/workflow/index.d.ts +14 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/memory.d.ts +17 -0
- package/dist/workflow/memory.d.ts.map +1 -0
- package/dist/workflow/memory.js +184 -0
- package/package.json +73 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Span exporters for the Runner SDK tracing pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `agent_engine_runner_shared/tracing/exporters.py`. Two exporters:
|
|
5
|
+
* - `JSONLSpanExporter` — optional explicit local debugging exporter.
|
|
6
|
+
* - `MongoDBSpanExporter` — inserts spans as documents into a Mongo collection.
|
|
7
|
+
*
|
|
8
|
+
* Both implement the `@opentelemetry/sdk-trace-base` `SpanExporter` interface.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExportResult } from "@opentelemetry/core";
|
|
11
|
+
import type { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
|
|
12
|
+
import type { Collection } from "mongodb";
|
|
13
|
+
/** Resolve the on-disk trace file path from env vars (mirrors Python). */
|
|
14
|
+
export declare function getTracePath(): string;
|
|
15
|
+
export declare class JSONLSpanExporter implements SpanExporter {
|
|
16
|
+
private readonly path;
|
|
17
|
+
constructor(path?: string);
|
|
18
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
|
|
19
|
+
shutdown(): Promise<void>;
|
|
20
|
+
forceFlush(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare class MongoDBSpanExporter implements SpanExporter {
|
|
23
|
+
private readonly collection;
|
|
24
|
+
constructor(collection: Collection);
|
|
25
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
|
|
26
|
+
shutdown(): Promise<void>;
|
|
27
|
+
forceFlush(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read the content-capture policy from `AGENTIC_PLATFORM_OTEL_CONTENT_CAPTURE`.
|
|
31
|
+
* Defaults to `"metadata-only"`; any value other than `"full"` is treated as
|
|
32
|
+
* `"metadata-only"` so a typo'd env var fails closed, not open.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getContentCaptureMode(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Wraps an OTLP `SpanExporter`, enforcing `AGENTIC_PLATFORM_OTEL_CONTENT_CAPTURE`.
|
|
37
|
+
* Redaction failures fail closed: a batch that can't be safely redacted is
|
|
38
|
+
* dropped rather than forwarded unredacted, matching the metadata-only
|
|
39
|
+
* default's privacy-first intent. Transport failures on the wrapped exporter
|
|
40
|
+
* never throw — they're surfaced only through `resultCallback`.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ContentPolicyOTLPSpanExporter implements SpanExporter {
|
|
43
|
+
private readonly inner;
|
|
44
|
+
private readonly contentCaptureMode;
|
|
45
|
+
constructor(inner: SpanExporter, contentCaptureMode?: string);
|
|
46
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
|
|
47
|
+
private exportInner;
|
|
48
|
+
shutdown(): Promise<void>;
|
|
49
|
+
forceFlush(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=exporters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporters.d.ts","sourceRoot":"","sources":["../../src/tracing/exporters.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAsB1C,0EAA0E;AAC1E,wBAAgB,YAAY,IAAI,MAAM,CAWrC;AAqDD,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBAEzB,IAAI,CAAC,EAAE,MAAM;IAIzB,MAAM,CACJ,KAAK,EAAE,YAAY,EAAE,EACrB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,IAAI;IAqBP,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAED,qBAAa,mBAAoB,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAEnD,MAAM,CACJ,KAAK,EAAE,YAAY,EAAE,EACrB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,IAAI;IAeP,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAyED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAS9C;AA6CD;;;;;;GAMG;AACH,qBAAa,6BAA8B,YAAW,YAAY;IAI9D,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHxB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAGzB,KAAK,EAAE,YAAY,EACpC,kBAAkB,CAAC,EAAE,MAAM;IAa7B,MAAM,CACJ,KAAK,EAAE,YAAY,EAAE,EACrB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,IAAI;IAyBP,OAAO,CAAC,WAAW;IAYnB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAM5B"}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Span exporters for the Runner SDK tracing pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `agent_engine_runner_shared/tracing/exporters.py`. Two exporters:
|
|
5
|
+
* - `JSONLSpanExporter` — optional explicit local debugging exporter.
|
|
6
|
+
* - `MongoDBSpanExporter` — inserts spans as documents into a Mongo collection.
|
|
7
|
+
*
|
|
8
|
+
* Both implement the `@opentelemetry/sdk-trace-base` `SpanExporter` interface.
|
|
9
|
+
*/
|
|
10
|
+
import { appendFileSync, mkdirSync, renameSync, statSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { getLogger } from "../logger.js";
|
|
13
|
+
const logger = getLogger("agent_engine_runner_shared.tracing");
|
|
14
|
+
const EXPORT_SUCCESS = 0; // ExportResultCode.SUCCESS
|
|
15
|
+
const EXPORT_FAILED = 1; // ExportResultCode.FAILED
|
|
16
|
+
const MAX_TRACE_FILE_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
17
|
+
function rotateIfNeeded(path) {
|
|
18
|
+
try {
|
|
19
|
+
const stat = statSync(path, { throwIfNoEntry: false });
|
|
20
|
+
if (stat && stat.size >= MAX_TRACE_FILE_BYTES) {
|
|
21
|
+
renameSync(path, path + ".1");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// best-effort — a failed rotation is better than crashing the exporter
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Resolve the on-disk trace file path from env vars (mirrors Python). */
|
|
29
|
+
export function getTracePath() {
|
|
30
|
+
let path;
|
|
31
|
+
if (process.env["AGENTIC_TRACES_FILE"]) {
|
|
32
|
+
path = process.env["AGENTIC_TRACES_FILE"];
|
|
33
|
+
}
|
|
34
|
+
else if (process.env["AGENTIC_OBSERVABILITY_DIR"]) {
|
|
35
|
+
path = join(process.env["AGENTIC_OBSERVABILITY_DIR"], "traces.jsonl");
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
path = join("observability", "traces.jsonl");
|
|
39
|
+
}
|
|
40
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
41
|
+
return path;
|
|
42
|
+
}
|
|
43
|
+
function spanToDoc(span) {
|
|
44
|
+
const ctx = span.spanContext();
|
|
45
|
+
const attributes = { ...span.attributes };
|
|
46
|
+
const sessionId = attributes["session.id"] ?? attributes["session_id"];
|
|
47
|
+
const executionId = attributes["execution.id"] ?? attributes["execution_id"];
|
|
48
|
+
const doc = {
|
|
49
|
+
trace_id: ctx.traceId,
|
|
50
|
+
span_id: ctx.spanId,
|
|
51
|
+
name: span.name,
|
|
52
|
+
kind: String(span.kind),
|
|
53
|
+
start_time_ns: hrtimeToNs(span.startTime),
|
|
54
|
+
end_time_ns: hrtimeToNs(span.endTime),
|
|
55
|
+
duration_ns: hrtimeDurationNs(span.startTime, span.endTime),
|
|
56
|
+
status: {
|
|
57
|
+
code: String(span.status.code),
|
|
58
|
+
description: span.status.message ?? null,
|
|
59
|
+
},
|
|
60
|
+
attributes,
|
|
61
|
+
resource: { ...(span.resource.attributes ?? {}) },
|
|
62
|
+
};
|
|
63
|
+
if (sessionId !== undefined)
|
|
64
|
+
doc["session_id"] = sessionId;
|
|
65
|
+
if (executionId !== undefined)
|
|
66
|
+
doc["execution_id"] = executionId;
|
|
67
|
+
if (span.parentSpanContext?.spanId) {
|
|
68
|
+
doc["parent_span_id"] = span.parentSpanContext.spanId;
|
|
69
|
+
}
|
|
70
|
+
if (span.events && span.events.length > 0) {
|
|
71
|
+
doc["events"] = span.events.map((e) => ({
|
|
72
|
+
name: e.name,
|
|
73
|
+
timestamp_ns: hrtimeToNs(e.time),
|
|
74
|
+
attributes: { ...(e.attributes ?? {}) },
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
return doc;
|
|
78
|
+
}
|
|
79
|
+
function hrtimeToNs(t) {
|
|
80
|
+
return t[0] * 1e9 + t[1];
|
|
81
|
+
}
|
|
82
|
+
function hrtimeDurationNs(start, end) {
|
|
83
|
+
return hrtimeToNs(end) - hrtimeToNs(start);
|
|
84
|
+
}
|
|
85
|
+
export class JSONLSpanExporter {
|
|
86
|
+
path;
|
|
87
|
+
constructor(path) {
|
|
88
|
+
this.path = path ?? null;
|
|
89
|
+
}
|
|
90
|
+
export(spans, resultCallback) {
|
|
91
|
+
if (spans.length === 0) {
|
|
92
|
+
resultCallback({ code: EXPORT_SUCCESS });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const target = this.path ?? getTracePath();
|
|
96
|
+
try {
|
|
97
|
+
rotateIfNeeded(target);
|
|
98
|
+
const lines = spans.map((s) => JSON.stringify(spanToDoc(s))).join("\n") + "\n";
|
|
99
|
+
appendFileSync(target, lines, { encoding: "utf-8" });
|
|
100
|
+
resultCallback({ code: EXPORT_SUCCESS });
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
logger.error({ path: target, err: err.message }, "Failed to write traces");
|
|
104
|
+
resultCallback({ code: EXPORT_FAILED, error: err });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
shutdown() {
|
|
108
|
+
return Promise.resolve();
|
|
109
|
+
}
|
|
110
|
+
forceFlush() {
|
|
111
|
+
return Promise.resolve();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export class MongoDBSpanExporter {
|
|
115
|
+
collection;
|
|
116
|
+
constructor(collection) {
|
|
117
|
+
this.collection = collection;
|
|
118
|
+
}
|
|
119
|
+
export(spans, resultCallback) {
|
|
120
|
+
if (spans.length === 0) {
|
|
121
|
+
resultCallback({ code: EXPORT_SUCCESS });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const docs = spans.map((s) => spanToDoc(s));
|
|
125
|
+
this.collection
|
|
126
|
+
.insertMany(docs)
|
|
127
|
+
.then(() => resultCallback({ code: EXPORT_SUCCESS }))
|
|
128
|
+
.catch((err) => {
|
|
129
|
+
logger.error({ err: err.message }, "Failed to write traces to MongoDB");
|
|
130
|
+
resultCallback({ code: EXPORT_FAILED, error: err });
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
shutdown() {
|
|
134
|
+
return Promise.resolve();
|
|
135
|
+
}
|
|
136
|
+
forceFlush() {
|
|
137
|
+
return Promise.resolve();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// =============================================================================
|
|
141
|
+
// Content-capture policy
|
|
142
|
+
//
|
|
143
|
+
// Mongo stays unredacted (customer's own BYOC DB, canonical for the
|
|
144
|
+
// playground). This policy applies only to the OTLP path, which leaves the
|
|
145
|
+
// process bound for a third-party tool. Ported from
|
|
146
|
+
// `agent_engine_runner_shared/tracing/exporters.py` — keep `REDACTED_KEY_FRAGMENTS` in
|
|
147
|
+
// sync with that module's `_REDACTED_KEY_FRAGMENTS`; a drifted copy either
|
|
148
|
+
// leaks content this list was meant to block, or over-redacts metadata.
|
|
149
|
+
// =============================================================================
|
|
150
|
+
const CONTENT_CAPTURE_ENV = "AGENTIC_PLATFORM_OTEL_CONTENT_CAPTURE";
|
|
151
|
+
const CONTENT_CAPTURE_FULL = "full";
|
|
152
|
+
const CONTENT_CAPTURE_METADATA_ONLY = "metadata-only";
|
|
153
|
+
// Substrings matched case-insensitively against attribute keys. OpenInference
|
|
154
|
+
// flattens nested/indexed fields (e.g. "llm.input_messages.0.message.content"),
|
|
155
|
+
// so this is fragment matching, not an exact-key set. See exporters.py for the
|
|
156
|
+
// full rationale (allowlist deliberately deferred, etc.) — this list must stay
|
|
157
|
+
// identical to Python's.
|
|
158
|
+
const REDACTED_KEY_FRAGMENTS = [
|
|
159
|
+
// Prompts / completions
|
|
160
|
+
"input.value",
|
|
161
|
+
"output.value",
|
|
162
|
+
"llm.input_messages",
|
|
163
|
+
"llm.output_messages",
|
|
164
|
+
"llm.prompts",
|
|
165
|
+
"llm.prompt_template.variables",
|
|
166
|
+
"llm.prompt_template.template",
|
|
167
|
+
"llm.invocation_parameters",
|
|
168
|
+
"message.content",
|
|
169
|
+
"message.function_call_arguments_json",
|
|
170
|
+
"tool_call.function.arguments",
|
|
171
|
+
"llm.function_call",
|
|
172
|
+
// Tool args/results
|
|
173
|
+
"tool.parameters",
|
|
174
|
+
"llm.tools",
|
|
175
|
+
// Retrieved docs
|
|
176
|
+
"retrieval.documents",
|
|
177
|
+
"document.content",
|
|
178
|
+
"reranker.query",
|
|
179
|
+
// Embeddings
|
|
180
|
+
"embedding.embeddings",
|
|
181
|
+
"embedding.text",
|
|
182
|
+
"embedding.vector",
|
|
183
|
+
"embedding.invocation_parameters",
|
|
184
|
+
// Memory contents
|
|
185
|
+
"memory.content",
|
|
186
|
+
"memory.value",
|
|
187
|
+
// Real end-user identifier
|
|
188
|
+
"user.id",
|
|
189
|
+
// Free-form metadata / exceptions
|
|
190
|
+
"metadata",
|
|
191
|
+
"exception.message",
|
|
192
|
+
"exception.stacktrace",
|
|
193
|
+
// Network / infra
|
|
194
|
+
"http.url",
|
|
195
|
+
"url.full",
|
|
196
|
+
"net.peer",
|
|
197
|
+
"server.address",
|
|
198
|
+
"net.sock.peer",
|
|
199
|
+
"db.connection_string",
|
|
200
|
+
// Secrets
|
|
201
|
+
"secret",
|
|
202
|
+
"password",
|
|
203
|
+
"credential",
|
|
204
|
+
"api_key",
|
|
205
|
+
"access_token",
|
|
206
|
+
"bearer",
|
|
207
|
+
];
|
|
208
|
+
/**
|
|
209
|
+
* Read the content-capture policy from `AGENTIC_PLATFORM_OTEL_CONTENT_CAPTURE`.
|
|
210
|
+
* Defaults to `"metadata-only"`; any value other than `"full"` is treated as
|
|
211
|
+
* `"metadata-only"` so a typo'd env var fails closed, not open.
|
|
212
|
+
*/
|
|
213
|
+
export function getContentCaptureMode() {
|
|
214
|
+
const mode = (process.env[CONTENT_CAPTURE_ENV] ?? CONTENT_CAPTURE_METADATA_ONLY)
|
|
215
|
+
.trim()
|
|
216
|
+
.toLowerCase();
|
|
217
|
+
return mode === CONTENT_CAPTURE_FULL
|
|
218
|
+
? CONTENT_CAPTURE_FULL
|
|
219
|
+
: CONTENT_CAPTURE_METADATA_ONLY;
|
|
220
|
+
}
|
|
221
|
+
function isRedactedAttributeKey(key) {
|
|
222
|
+
const lowered = key.toLowerCase();
|
|
223
|
+
return REDACTED_KEY_FRAGMENTS.some((fragment) => lowered.includes(fragment));
|
|
224
|
+
}
|
|
225
|
+
function redactAttributes(attributes) {
|
|
226
|
+
if (!attributes)
|
|
227
|
+
return {};
|
|
228
|
+
const redacted = {};
|
|
229
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
230
|
+
if (!isRedactedAttributeKey(key))
|
|
231
|
+
redacted[key] = value;
|
|
232
|
+
}
|
|
233
|
+
return redacted;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Return a copy of `span` with content-bearing attributes (and event
|
|
237
|
+
* attributes) stripped.
|
|
238
|
+
*
|
|
239
|
+
* A real SDK `Span` exposes `spanContext()` (and other members) as methods
|
|
240
|
+
* on its prototype, not as own enumerable properties — a plain `{ ...span }`
|
|
241
|
+
* spread silently drops them, so anything downstream that calls
|
|
242
|
+
* `span.spanContext()` (e.g. the OTLP transformer) throws
|
|
243
|
+
* "span.spanContext is not a function". `Object.create(span)` instead makes
|
|
244
|
+
* `span` itself the new object's prototype: every unlisted member (methods
|
|
245
|
+
* and data alike) falls through the prototype chain to the original span
|
|
246
|
+
* unchanged, and only `attributes`/`events` are shadowed as own properties.
|
|
247
|
+
*/
|
|
248
|
+
function redactSpan(span) {
|
|
249
|
+
const redacted = Object.create(span);
|
|
250
|
+
Object.defineProperty(redacted, "attributes", {
|
|
251
|
+
value: redactAttributes(span.attributes),
|
|
252
|
+
enumerable: true,
|
|
253
|
+
});
|
|
254
|
+
Object.defineProperty(redacted, "events", {
|
|
255
|
+
value: (span.events ?? []).map((e) => ({
|
|
256
|
+
...e,
|
|
257
|
+
attributes: redactAttributes(e.attributes),
|
|
258
|
+
})),
|
|
259
|
+
enumerable: true,
|
|
260
|
+
});
|
|
261
|
+
return redacted;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Wraps an OTLP `SpanExporter`, enforcing `AGENTIC_PLATFORM_OTEL_CONTENT_CAPTURE`.
|
|
265
|
+
* Redaction failures fail closed: a batch that can't be safely redacted is
|
|
266
|
+
* dropped rather than forwarded unredacted, matching the metadata-only
|
|
267
|
+
* default's privacy-first intent. Transport failures on the wrapped exporter
|
|
268
|
+
* never throw — they're surfaced only through `resultCallback`.
|
|
269
|
+
*/
|
|
270
|
+
export class ContentPolicyOTLPSpanExporter {
|
|
271
|
+
inner;
|
|
272
|
+
contentCaptureMode;
|
|
273
|
+
constructor(inner, contentCaptureMode) {
|
|
274
|
+
this.inner = inner;
|
|
275
|
+
if (contentCaptureMode !== undefined) {
|
|
276
|
+
const normalized = contentCaptureMode.trim().toLowerCase();
|
|
277
|
+
this.contentCaptureMode =
|
|
278
|
+
normalized === CONTENT_CAPTURE_FULL
|
|
279
|
+
? CONTENT_CAPTURE_FULL
|
|
280
|
+
: CONTENT_CAPTURE_METADATA_ONLY;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
this.contentCaptureMode = getContentCaptureMode();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export(spans, resultCallback) {
|
|
287
|
+
if (spans.length === 0) {
|
|
288
|
+
resultCallback({ code: EXPORT_SUCCESS });
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (this.contentCaptureMode === CONTENT_CAPTURE_FULL) {
|
|
292
|
+
this.exportInner(spans, resultCallback);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
let redacted;
|
|
296
|
+
try {
|
|
297
|
+
redacted = spans.map((span) => redactSpan(span));
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
logger.error({ err: err.message }, "Content-capture redaction failed; dropping batch rather than risk exporting unredacted content");
|
|
301
|
+
resultCallback({ code: EXPORT_FAILED, error: err });
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
this.exportInner(redacted, resultCallback);
|
|
305
|
+
}
|
|
306
|
+
exportInner(spans, resultCallback) {
|
|
307
|
+
try {
|
|
308
|
+
this.inner.export(spans, resultCallback);
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
logger.error({ err: err.message }, "OTLP export failed");
|
|
312
|
+
resultCallback({ code: EXPORT_FAILED, error: err });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
shutdown() {
|
|
316
|
+
return Promise.resolve(this.inner.shutdown()).catch((err) => {
|
|
317
|
+
logger.error({ err: err.message }, "OTLP exporter shutdown failed");
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
forceFlush() {
|
|
321
|
+
if (this.inner.forceFlush === undefined)
|
|
322
|
+
return Promise.resolve();
|
|
323
|
+
return Promise.resolve(this.inner.forceFlush()).catch((err) => {
|
|
324
|
+
logger.error({ err: err.message }, "OTLP exporter force_flush failed");
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ContentPolicyOTLPSpanExporter, JSONLSpanExporter, MongoDBSpanExporter, getContentCaptureMode, getTracePath, } from "./exporters.js";
|
|
2
|
+
export { setupTracing, shutdownTracing, attachMongoTracing, tracingStatus, getCurrentTraceContext, getTracer, runInstrumentor, scrubCredentials, type SetupTracingArgs, } from "./setup.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { ContentPolicyOTLPSpanExporter, JSONLSpanExporter, MongoDBSpanExporter, getContentCaptureMode, getTracePath, } from "./exporters.js";
|
|
2
|
+
export { setupTracing, shutdownTracing, attachMongoTracing, tracingStatus, getCurrentTraceContext, getTracer, runInstrumentor, scrubCredentials, } from "./setup.js";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracing setup for Runner SDK.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `agent_engine_runner_shared/tracing/setup.py`. Initializes OpenTelemetry
|
|
5
|
+
* with `BasicTracerProvider` and optionally a Mongo exporter. Calls the
|
|
6
|
+
* framework instrumentor hook
|
|
7
|
+
* registered via `agent_engine_runner_shared/hooks.ts:registerInstrumentor`.
|
|
8
|
+
*/
|
|
9
|
+
import type { Tracer } from "@opentelemetry/api";
|
|
10
|
+
import type { Collection } from "mongodb";
|
|
11
|
+
export interface SetupTracingArgs {
|
|
12
|
+
serviceName?: string;
|
|
13
|
+
/**
|
|
14
|
+
* URI for the trace store. When provided, `setupTracing` builds the
|
|
15
|
+
* MongoClient, pings `admin`, and resolves the `(database, collection)`
|
|
16
|
+
* itself.
|
|
17
|
+
*
|
|
18
|
+
* Python's `TenantRuntime._setup_tracing` does this synchronously and
|
|
19
|
+
* passes the collection in; Node's driver is fundamentally async so the
|
|
20
|
+
* connect + ping live here instead. After a connection failure, a background
|
|
21
|
+
* retry attaches the MongoDB exporter once the store recovers —
|
|
22
|
+
* same recovery shape as Python.
|
|
23
|
+
*/
|
|
24
|
+
mongodbUri?: string | null;
|
|
25
|
+
/** Explicit database override. Omit to use the platform store default. */
|
|
26
|
+
mongodbDatabaseName?: string | null;
|
|
27
|
+
/** Collection name within `mongodbDatabaseName`. Defaults to `"traces"`. */
|
|
28
|
+
mongodbCollectionName?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Mask the userinfo of any `mongodb://` / `mongodb+srv://` URI embedded in a
|
|
32
|
+
* credential-bearing error message (driver parse/connect errors echo the raw
|
|
33
|
+
* connection string).
|
|
34
|
+
*
|
|
35
|
+
* The userinfo run is GREEDY up to the LAST '@' that a host-shaped token
|
|
36
|
+
* follows, so passwords containing an unescaped '@', space, or '/' are still
|
|
37
|
+
* fully masked — the old `:\/\/[^@\s]+@` pattern stopped at the first '@' and
|
|
38
|
+
* could not cross whitespace, leaking the password tail (or the whole
|
|
39
|
+
* userinfo) to the centralized log sink. The run is tempered so it never
|
|
40
|
+
* crosses into a second URI's scheme; when message text after the URI
|
|
41
|
+
* contains its own '@' the mask may extend to it — over-redaction is the
|
|
42
|
+
* fail-closed direction, a leak is not recoverable. Keep in sync with
|
|
43
|
+
* `scrub_credentials` in Python's `agent_engine_runner_shared/tracing/setup.py`.
|
|
44
|
+
*
|
|
45
|
+
* Accepts `unknown` and coerces: error paths hand this whatever a rejection
|
|
46
|
+
* carried (string throws, objects without a string `message`, undefined) —
|
|
47
|
+
* it must never throw itself, or a degraded trace store turns into a
|
|
48
|
+
* startup failure.
|
|
49
|
+
*/
|
|
50
|
+
export declare function scrubCredentials(message: unknown): string;
|
|
51
|
+
export declare function setupTracing(args?: SetupTracingArgs): Promise<void>;
|
|
52
|
+
export declare function runInstrumentor(): void;
|
|
53
|
+
export declare function shutdownTracing(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Snapshot of the database trace-store exporter for /health. Mirrors Python's
|
|
56
|
+
* `tracing_status`: `"attached"` (MongoDB span processor live), `"degraded"`
|
|
57
|
+
* (store URI configured but unreachable at startup, retrying), or `"disabled"`
|
|
58
|
+
* (no store URI configured, not a degradation).
|
|
59
|
+
*/
|
|
60
|
+
export declare function tracingStatus(): {
|
|
61
|
+
database_exporter: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Wire the recovered trace-store collection into the lazy Mongo exporter
|
|
65
|
+
* registered at setup time. Called from the background retry loop
|
|
66
|
+
* once a failed connection recovers. Idempotent — a no-op if already attached.
|
|
67
|
+
* New spans created after this call route to the store; spans emitted while the
|
|
68
|
+
* store was unreachable are not retroactively recovered.
|
|
69
|
+
*/
|
|
70
|
+
export declare function attachMongoTracing(collection: Collection): void;
|
|
71
|
+
export declare function getCurrentTraceContext(): {
|
|
72
|
+
traceId: string | null;
|
|
73
|
+
spanId: string | null;
|
|
74
|
+
};
|
|
75
|
+
export declare function getTracer(name?: string): Tracer;
|
|
76
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/tracing/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAW,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAe1D,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;AA4GvD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAqDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CASzD;AAsED,wBAAsB,YAAY,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7E;AA8DD,wBAAgB,eAAe,IAAI,IAAI,CAiBtC;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAgCrD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAI7D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAmB/D;AAwDD,wBAAgB,sBAAsB,IAAI;IACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAMA;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAe,GAAG,MAAM,CAErD"}
|