@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.
Files changed (220) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/LICENSE.md +201 -0
  3. package/README.md +29 -0
  4. package/dist/agent_config.d.ts +167 -0
  5. package/dist/agent_config.d.ts.map +1 -0
  6. package/dist/agent_config.js +544 -0
  7. package/dist/call_interrupted.d.ts +12 -0
  8. package/dist/call_interrupted.d.ts.map +1 -0
  9. package/dist/call_interrupted.js +11 -0
  10. package/dist/checkpoint_workspace.d.ts +25 -0
  11. package/dist/checkpoint_workspace.d.ts.map +1 -0
  12. package/dist/checkpoint_workspace.js +44 -0
  13. package/dist/context.d.ts +235 -0
  14. package/dist/context.d.ts.map +1 -0
  15. package/dist/context.js +322 -0
  16. package/dist/db_config.d.ts +28 -0
  17. package/dist/db_config.d.ts.map +1 -0
  18. package/dist/db_config.js +66 -0
  19. package/dist/db_naming.d.ts +54 -0
  20. package/dist/db_naming.d.ts.map +1 -0
  21. package/dist/db_naming.js +94 -0
  22. package/dist/error_reporting.d.ts +67 -0
  23. package/dist/error_reporting.d.ts.map +1 -0
  24. package/dist/error_reporting.js +311 -0
  25. package/dist/generated/workflow/v1/activity_pb.d.ts +342 -0
  26. package/dist/generated/workflow/v1/activity_pb.d.ts.map +1 -0
  27. package/dist/generated/workflow/v1/activity_pb.js +115 -0
  28. package/dist/generated/workflow/v1/common_pb.d.ts +184 -0
  29. package/dist/generated/workflow/v1/common_pb.d.ts.map +1 -0
  30. package/dist/generated/workflow/v1/common_pb.js +86 -0
  31. package/dist/generated/workflow/v1/runtime_pb.d.ts +200 -0
  32. package/dist/generated/workflow/v1/runtime_pb.d.ts.map +1 -0
  33. package/dist/generated/workflow/v1/runtime_pb.js +40 -0
  34. package/dist/generated/workflow/v1/state_pb.d.ts +254 -0
  35. package/dist/generated/workflow/v1/state_pb.d.ts.map +1 -0
  36. package/dist/generated/workflow/v1/state_pb.js +68 -0
  37. package/dist/guardrails_evaluator/core.d.ts +23 -0
  38. package/dist/guardrails_evaluator/core.d.ts.map +1 -0
  39. package/dist/guardrails_evaluator/core.js +122 -0
  40. package/dist/guardrails_evaluator/index.d.ts +10 -0
  41. package/dist/guardrails_evaluator/index.d.ts.map +1 -0
  42. package/dist/guardrails_evaluator/index.js +11 -0
  43. package/dist/guardrails_evaluator/regex.d.ts +20 -0
  44. package/dist/guardrails_evaluator/regex.d.ts.map +1 -0
  45. package/dist/guardrails_evaluator/regex.js +233 -0
  46. package/dist/hooks.d.ts +109 -0
  47. package/dist/hooks.d.ts.map +1 -0
  48. package/dist/hooks.js +216 -0
  49. package/dist/http_path.d.ts +18 -0
  50. package/dist/http_path.d.ts.map +1 -0
  51. package/dist/http_path.js +53 -0
  52. package/dist/index.d.ts +35 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +41 -0
  55. package/dist/launcher.d.ts +130 -0
  56. package/dist/launcher.d.ts.map +1 -0
  57. package/dist/launcher.js +325 -0
  58. package/dist/logger.d.ts +96 -0
  59. package/dist/logger.d.ts.map +1 -0
  60. package/dist/logger.js +204 -0
  61. package/dist/mcp_oauth.d.ts +51 -0
  62. package/dist/mcp_oauth.d.ts.map +1 -0
  63. package/dist/mcp_oauth.js +389 -0
  64. package/dist/mcp_oauth_secret.d.ts +21 -0
  65. package/dist/mcp_oauth_secret.d.ts.map +1 -0
  66. package/dist/mcp_oauth_secret.js +122 -0
  67. package/dist/mcp_tools.d.ts +71 -0
  68. package/dist/mcp_tools.d.ts.map +1 -0
  69. package/dist/mcp_tools.js +301 -0
  70. package/dist/memory_appbound.d.ts +42 -0
  71. package/dist/memory_appbound.d.ts.map +1 -0
  72. package/dist/memory_appbound.js +159 -0
  73. package/dist/memory_writer.d.ts +49 -0
  74. package/dist/memory_writer.d.ts.map +1 -0
  75. package/dist/memory_writer.js +171 -0
  76. package/dist/metrics.d.ts +84 -0
  77. package/dist/metrics.d.ts.map +1 -0
  78. package/dist/metrics.js +205 -0
  79. package/dist/models.d.ts +1458 -0
  80. package/dist/models.d.ts.map +1 -0
  81. package/dist/models.js +1726 -0
  82. package/dist/node_logger.d.ts +43 -0
  83. package/dist/node_logger.d.ts.map +1 -0
  84. package/dist/node_logger.js +158 -0
  85. package/dist/owner_callback.d.ts +16 -0
  86. package/dist/owner_callback.d.ts.map +1 -0
  87. package/dist/owner_callback.js +40 -0
  88. package/dist/progress.d.ts +57 -0
  89. package/dist/progress.d.ts.map +1 -0
  90. package/dist/progress.js +140 -0
  91. package/dist/runtime.d.ts +131 -0
  92. package/dist/runtime.d.ts.map +1 -0
  93. package/dist/runtime.js +351 -0
  94. package/dist/secure_llm_proxy.d.ts +115 -0
  95. package/dist/secure_llm_proxy.d.ts.map +1 -0
  96. package/dist/secure_llm_proxy.js +922 -0
  97. package/dist/secure_wrapper.d.ts +332 -0
  98. package/dist/secure_wrapper.d.ts.map +1 -0
  99. package/dist/secure_wrapper.js +1249 -0
  100. package/dist/server/aer.d.ts +61 -0
  101. package/dist/server/aer.d.ts.map +1 -0
  102. package/dist/server/aer.js +1124 -0
  103. package/dist/server/auth.d.ts +56 -0
  104. package/dist/server/auth.d.ts.map +1 -0
  105. package/dist/server/auth.js +132 -0
  106. package/dist/server/base.d.ts +104 -0
  107. package/dist/server/base.d.ts.map +1 -0
  108. package/dist/server/base.js +150 -0
  109. package/dist/server/callInterrupt.d.ts +49 -0
  110. package/dist/server/callInterrupt.d.ts.map +1 -0
  111. package/dist/server/callInterrupt.js +68 -0
  112. package/dist/server/callback_delivery.d.ts +14 -0
  113. package/dist/server/callback_delivery.d.ts.map +1 -0
  114. package/dist/server/callback_delivery.js +141 -0
  115. package/dist/server/chunk_types.d.ts +50 -0
  116. package/dist/server/chunk_types.d.ts.map +1 -0
  117. package/dist/server/chunk_types.js +62 -0
  118. package/dist/server/cors.d.ts +52 -0
  119. package/dist/server/cors.d.ts.map +1 -0
  120. package/dist/server/cors.js +107 -0
  121. package/dist/server/drain.d.ts +169 -0
  122. package/dist/server/drain.d.ts.map +1 -0
  123. package/dist/server/drain.js +455 -0
  124. package/dist/server/function.d.ts +77 -0
  125. package/dist/server/function.d.ts.map +1 -0
  126. package/dist/server/function.js +337 -0
  127. package/dist/server/http_retry.d.ts +37 -0
  128. package/dist/server/http_retry.d.ts.map +1 -0
  129. package/dist/server/http_retry.js +157 -0
  130. package/dist/server/index.d.ts +7 -0
  131. package/dist/server/index.d.ts.map +1 -0
  132. package/dist/server/index.js +5 -0
  133. package/dist/server/metadata.d.ts +50 -0
  134. package/dist/server/metadata.d.ts.map +1 -0
  135. package/dist/server/metadata.js +193 -0
  136. package/dist/server/oe_url.d.ts +36 -0
  137. package/dist/server/oe_url.d.ts.map +1 -0
  138. package/dist/server/oe_url.js +50 -0
  139. package/dist/server/owner_url.d.ts +35 -0
  140. package/dist/server/owner_url.d.ts.map +1 -0
  141. package/dist/server/owner_url.js +146 -0
  142. package/dist/server/query.d.ts +42 -0
  143. package/dist/server/query.d.ts.map +1 -0
  144. package/dist/server/query.js +28 -0
  145. package/dist/server/tool.d.ts +138 -0
  146. package/dist/server/tool.d.ts.map +1 -0
  147. package/dist/server/tool.js +1017 -0
  148. package/dist/span_names.d.ts +21 -0
  149. package/dist/span_names.d.ts.map +1 -0
  150. package/dist/span_names.js +31 -0
  151. package/dist/structured_logging/constants.d.ts +17 -0
  152. package/dist/structured_logging/constants.d.ts.map +1 -0
  153. package/dist/structured_logging/constants.js +71 -0
  154. package/dist/structured_logging/env.d.ts +18 -0
  155. package/dist/structured_logging/env.d.ts.map +1 -0
  156. package/dist/structured_logging/env.js +39 -0
  157. package/dist/structured_logging/install.d.ts +56 -0
  158. package/dist/structured_logging/install.d.ts.map +1 -0
  159. package/dist/structured_logging/install.js +107 -0
  160. package/dist/structured_logging/layout.d.ts +9 -0
  161. package/dist/structured_logging/layout.d.ts.map +1 -0
  162. package/dist/structured_logging/layout.js +144 -0
  163. package/dist/structured_logging/serialize.d.ts +27 -0
  164. package/dist/structured_logging/serialize.d.ts.map +1 -0
  165. package/dist/structured_logging/serialize.js +61 -0
  166. package/dist/structured_logging/stdio_capture.d.ts +59 -0
  167. package/dist/structured_logging/stdio_capture.d.ts.map +1 -0
  168. package/dist/structured_logging/stdio_capture.js +164 -0
  169. package/dist/structured_logging/uncaught.d.ts +14 -0
  170. package/dist/structured_logging/uncaught.d.ts.map +1 -0
  171. package/dist/structured_logging/uncaught.js +58 -0
  172. package/dist/structured_logging.d.ts +48 -0
  173. package/dist/structured_logging.d.ts.map +1 -0
  174. package/dist/structured_logging.js +47 -0
  175. package/dist/tls_client.d.ts +61 -0
  176. package/dist/tls_client.d.ts.map +1 -0
  177. package/dist/tls_client.js +298 -0
  178. package/dist/tool_api_error.d.ts +62 -0
  179. package/dist/tool_api_error.d.ts.map +1 -0
  180. package/dist/tool_api_error.js +399 -0
  181. package/dist/tool_memory_ownership.d.ts +10 -0
  182. package/dist/tool_memory_ownership.d.ts.map +1 -0
  183. package/dist/tool_memory_ownership.js +36 -0
  184. package/dist/toolpod_handlers.d.ts +126 -0
  185. package/dist/toolpod_handlers.d.ts.map +1 -0
  186. package/dist/toolpod_handlers.js +1016 -0
  187. package/dist/tracing/exporters.d.ts +51 -0
  188. package/dist/tracing/exporters.d.ts.map +1 -0
  189. package/dist/tracing/exporters.js +327 -0
  190. package/dist/tracing/index.d.ts +3 -0
  191. package/dist/tracing/index.d.ts.map +1 -0
  192. package/dist/tracing/index.js +2 -0
  193. package/dist/tracing/setup.d.ts +76 -0
  194. package/dist/tracing/setup.d.ts.map +1 -0
  195. package/dist/tracing/setup.js +436 -0
  196. package/dist/utils.d.ts +204 -0
  197. package/dist/utils.d.ts.map +1 -0
  198. package/dist/utils.js +867 -0
  199. package/dist/workflow/activity.d.ts +71 -0
  200. package/dist/workflow/activity.d.ts.map +1 -0
  201. package/dist/workflow/activity.js +357 -0
  202. package/dist/workflow/attempt.d.ts +12 -0
  203. package/dist/workflow/attempt.d.ts.map +1 -0
  204. package/dist/workflow/attempt.js +96 -0
  205. package/dist/workflow/client.d.ts +46 -0
  206. package/dist/workflow/client.d.ts.map +1 -0
  207. package/dist/workflow/client.js +299 -0
  208. package/dist/workflow/context.d.ts +37 -0
  209. package/dist/workflow/context.d.ts.map +1 -0
  210. package/dist/workflow/context.js +350 -0
  211. package/dist/workflow/heartbeat.d.ts +15 -0
  212. package/dist/workflow/heartbeat.d.ts.map +1 -0
  213. package/dist/workflow/heartbeat.js +78 -0
  214. package/dist/workflow/index.d.ts +14 -0
  215. package/dist/workflow/index.d.ts.map +1 -0
  216. package/dist/workflow/index.js +10 -0
  217. package/dist/workflow/memory.d.ts +17 -0
  218. package/dist/workflow/memory.d.ts.map +1 -0
  219. package/dist/workflow/memory.js +184 -0
  220. 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"}