@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,59 @@
1
+ /**
2
+ * Capture of `process.stdout` / `process.stderr` writes so stray
3
+ * `console.log` / direct writes emerge as structured-logging records tagged
4
+ * `source: "stdout"` / `"stderr"`.
5
+ */
6
+ import { type Logger } from "log4js";
7
+ import { ORIGINAL_WRITE_SLOT } from "./constants.js";
8
+ type WriteFn = NodeJS.WriteStream["write"];
9
+ type PatchableStream = NodeJS.WriteStream & {
10
+ [ORIGINAL_WRITE_SLOT]?: WriteFn;
11
+ };
12
+ /**
13
+ * Snapshot the original `write` on the first install and stash it on the
14
+ * stream under `ORIGINAL_WRITE_SLOT`. Subsequent calls return the same
15
+ * snapshot — matches the Python `_unwrap_logging_stream` recursion guard:
16
+ * the appender always writes via the snapshot, never via the patched
17
+ * `write` we've installed on top.
18
+ */
19
+ export declare function snapshotOriginalWrite(stream: PatchableStream): WriteFn;
20
+ /**
21
+ * Replacement for `process.stdout.write` / `process.stderr.write` that
22
+ * routes writes through a logger.
23
+ *
24
+ * Bare `console.log` / `process.stdout.write` calls (and any other code
25
+ * writing directly to the captured stream) are rewritten as log records
26
+ * tagged with `source: "stdout"` (or `"stderr"`) so the layout can mark
27
+ * them as such on the wire. Lines are buffered until newline, with a hard
28
+ * byte cap so a producer writing without `\n` cannot grow the buffer
29
+ * until OOM (see `MAX_BUFFER_BYTES`).
30
+ *
31
+ * Unlike the Python `LoggingStream` we do not need an `RLock` — Node's
32
+ * event loop is single-threaded, so concurrent `write()` calls can't
33
+ * interleave bytes mid-line. We also don't reproduce Python's
34
+ * `fileno()`/`buffer`/`encoding` delegation: we only patch the `write`
35
+ * method, leaving `process.stdout`'s fd / TTY introspection intact for
36
+ * subprocess piping, progress-bar libs, and grpc-internal logging.
37
+ */
38
+ /** @internal — exported only for tests; not part of the public API. */
39
+ export declare class LoggingStream {
40
+ private readonly logger;
41
+ private readonly level;
42
+ private readonly source;
43
+ private buffer;
44
+ constructor(logger: Logger, level: "info" | "warn", source: "stdout" | "stderr");
45
+ write(chunk: unknown, encodingOrCb?: unknown, maybeCb?: unknown): boolean;
46
+ /**
47
+ * Emit any buffered bytes that never got a trailing newline, then clear the
48
+ * buffer. Called on process exit so a final `console.log`/`process.stdout.
49
+ * write` without a `\n` right before shutdown is not lost — mirrors Python's
50
+ * `LoggingStream.flush()` (which the interpreter invokes when it flushes
51
+ * `sys.stdout` at shutdown). The same whitespace-only skip as `write()`
52
+ * applies: a blank tail is not worth a record.
53
+ */
54
+ flush(): void;
55
+ private emit;
56
+ }
57
+ export declare function patchStdio(): void;
58
+ export {};
59
+ //# sourceMappingURL=stdio_capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio_capture.d.ts","sourceRoot":"","sources":["../../src/structured_logging/stdio_capture.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAIL,mBAAmB,EAEpB,MAAM,gBAAgB,CAAC;AAGxB,KAAK,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC3C,KAAK,eAAe,GAAG,MAAM,CAAC,WAAW,GAAG;IAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAMtE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,uEAAuE;AACvE,qBAAa,aAAa;IAItB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,MAAM,CAAM;gBAGD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,MAAM,EAAE,QAAQ,GAAG,QAAQ;IAG9C,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO;IA4CzE;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,IAAI;CAOb;AAED,wBAAgB,UAAU,IAAI,IAAI,CAwDjC"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Capture of `process.stdout` / `process.stderr` writes so stray
3
+ * `console.log` / direct writes emerge as structured-logging records tagged
4
+ * `source: "stdout"` / `"stderr"`.
5
+ */
6
+ import log4js from "log4js";
7
+ import { ACTIVE_CAPTURES, EXIT_FLUSH_REGISTERED, MAX_BUFFER_BYTES, ORIGINAL_WRITE_SLOT, STDIO_CAPTURE_CATEGORY, } from "./constants.js";
8
+ import { truncateUtf8 } from "./serialize.js";
9
+ /**
10
+ * Snapshot the original `write` on the first install and stash it on the
11
+ * stream under `ORIGINAL_WRITE_SLOT`. Subsequent calls return the same
12
+ * snapshot — matches the Python `_unwrap_logging_stream` recursion guard:
13
+ * the appender always writes via the snapshot, never via the patched
14
+ * `write` we've installed on top.
15
+ */
16
+ export function snapshotOriginalWrite(stream) {
17
+ const existing = stream[ORIGINAL_WRITE_SLOT];
18
+ if (existing)
19
+ return existing;
20
+ const original = stream.write.bind(stream);
21
+ stream[ORIGINAL_WRITE_SLOT] = original;
22
+ return original;
23
+ }
24
+ /**
25
+ * Replacement for `process.stdout.write` / `process.stderr.write` that
26
+ * routes writes through a logger.
27
+ *
28
+ * Bare `console.log` / `process.stdout.write` calls (and any other code
29
+ * writing directly to the captured stream) are rewritten as log records
30
+ * tagged with `source: "stdout"` (or `"stderr"`) so the layout can mark
31
+ * them as such on the wire. Lines are buffered until newline, with a hard
32
+ * byte cap so a producer writing without `\n` cannot grow the buffer
33
+ * until OOM (see `MAX_BUFFER_BYTES`).
34
+ *
35
+ * Unlike the Python `LoggingStream` we do not need an `RLock` — Node's
36
+ * event loop is single-threaded, so concurrent `write()` calls can't
37
+ * interleave bytes mid-line. We also don't reproduce Python's
38
+ * `fileno()`/`buffer`/`encoding` delegation: we only patch the `write`
39
+ * method, leaving `process.stdout`'s fd / TTY introspection intact for
40
+ * subprocess piping, progress-bar libs, and grpc-internal logging.
41
+ */
42
+ /** @internal — exported only for tests; not part of the public API. */
43
+ export class LoggingStream {
44
+ logger;
45
+ level;
46
+ source;
47
+ buffer = "";
48
+ constructor(logger, level, source) {
49
+ this.logger = logger;
50
+ this.level = level;
51
+ this.source = source;
52
+ }
53
+ write(chunk, encodingOrCb, maybeCb) {
54
+ const text = typeof chunk === "string"
55
+ ? chunk
56
+ : Buffer.isBuffer(chunk)
57
+ ? chunk.toString(typeof encodingOrCb === "string"
58
+ ? encodingOrCb
59
+ : "utf-8")
60
+ : String(chunk ?? "");
61
+ if (text) {
62
+ this.buffer += text;
63
+ let newlineIdx = this.buffer.indexOf("\n");
64
+ while (newlineIdx !== -1) {
65
+ const line = this.buffer.slice(0, newlineIdx);
66
+ this.buffer = this.buffer.slice(newlineIdx + 1);
67
+ // Whitespace-only lines are uninteresting — emitting a JSON
68
+ // record with `message: " "` adds noise and makes downstream
69
+ // filters work harder. Mirrors the `if line.strip()` filter in
70
+ // the Python LoggingStream; do not "fix" by removing it.
71
+ if (line.trim())
72
+ this.emit(line);
73
+ newlineIdx = this.buffer.indexOf("\n");
74
+ }
75
+ // Force-emit a truncated record if a producer is writing without
76
+ // newlines — mirrors the exc_traceback truncation pattern. Slice
77
+ // by UTF-8 byte count via `truncateUtf8` so the cap reflects what
78
+ // Fluent Bit ships AND a partial multi-byte sequence at the cut
79
+ // point is dropped rather than turned into U+FFFD replacement bytes
80
+ // that would push the encoded payload back over the budget.
81
+ if (Buffer.byteLength(this.buffer, "utf-8") > MAX_BUFFER_BYTES) {
82
+ this.emit(truncateUtf8(this.buffer, MAX_BUFFER_BYTES));
83
+ this.buffer = "";
84
+ }
85
+ }
86
+ // Honor `write(chunk, cb)` and `write(chunk, encoding, cb)` callback
87
+ // signatures so callers waiting on drain semantics don't hang.
88
+ const cb = typeof encodingOrCb === "function" ? encodingOrCb : maybeCb;
89
+ if (typeof cb === "function")
90
+ cb();
91
+ return true;
92
+ }
93
+ /**
94
+ * Emit any buffered bytes that never got a trailing newline, then clear the
95
+ * buffer. Called on process exit so a final `console.log`/`process.stdout.
96
+ * write` without a `\n` right before shutdown is not lost — mirrors Python's
97
+ * `LoggingStream.flush()` (which the interpreter invokes when it flushes
98
+ * `sys.stdout` at shutdown). The same whitespace-only skip as `write()`
99
+ * applies: a blank tail is not worth a record.
100
+ */
101
+ flush() {
102
+ if (this.buffer.trim())
103
+ this.emit(this.buffer);
104
+ this.buffer = "";
105
+ }
106
+ emit(line) {
107
+ if (this.level === "warn") {
108
+ this.logger.warn({ source: this.source }, line);
109
+ }
110
+ else {
111
+ this.logger.info({ source: this.source }, line);
112
+ }
113
+ }
114
+ }
115
+ export function patchStdio() {
116
+ const stdoutStream = process.stdout;
117
+ const stderrStream = process.stderr;
118
+ // Snapshot before patching even though we don't reference the result
119
+ // here — ensures the slot is populated for the appender below, and
120
+ // protects against a re-install wrapping our already-patched `write`.
121
+ snapshotOriginalWrite(stdoutStream);
122
+ snapshotOriginalWrite(stderrStream);
123
+ // Pull from the dedicated capture category (configured at `trace` in
124
+ // installStructuredLogging) instead of the root logger — see the
125
+ // STDIO_CAPTURE_CATEGORY comment for why. Routing through the root would
126
+ // inherit the operator-set LOG_LEVEL and silently drop stray
127
+ // `console.log` lines when LOG_LEVEL=WARN/ERROR, which is the exact
128
+ // behaviour Python's `Logger.handle()` bypass was added to prevent.
129
+ const captureLogger = log4js.getLogger(STDIO_CAPTURE_CATEGORY);
130
+ const stdoutCapture = new LoggingStream(captureLogger, "info", "stdout");
131
+ const stderrCapture = new LoggingStream(captureLogger, "warn", "stderr");
132
+ stdoutStream.write = stdoutCapture.write.bind(stdoutCapture);
133
+ stderrStream.write = stderrCapture.write.bind(stderrCapture);
134
+ // Flush any buffered tail (a final write without a trailing newline) on
135
+ // process exit so it isn't lost — the parity counterpart to Python's stdout
136
+ // flush at interpreter shutdown. The handler is registered once per process
137
+ // (`Symbol.for` guards against stacking one on every re-install), but it
138
+ // must flush the *currently* installed capture streams, not the ones from
139
+ // the first install it happened to close over. So the streams live in a
140
+ // shared global slot that every patchStdio call overwrites, and the handler
141
+ // reads that slot at exit time.
142
+ const g = globalThis;
143
+ // Flush the outgoing streams before dropping the reference to them: a
144
+ // re-install replaces process.stdout.write, so a partial (newline-less) line
145
+ // buffered in the previous capture would otherwise never be emitted anywhere
146
+ // — it's not carried over to the new stream, and the exit handler only sees
147
+ // whatever is current in ACTIVE_CAPTURES.
148
+ const prev = g[ACTIVE_CAPTURES];
149
+ if (prev) {
150
+ prev.stdout.flush();
151
+ prev.stderr.flush();
152
+ }
153
+ g[ACTIVE_CAPTURES] = { stdout: stdoutCapture, stderr: stderrCapture };
154
+ if (!g[EXIT_FLUSH_REGISTERED]) {
155
+ g[EXIT_FLUSH_REGISTERED] = true;
156
+ process.on("exit", () => {
157
+ const active = g[ACTIVE_CAPTURES];
158
+ if (active) {
159
+ active.stdout.flush();
160
+ active.stderr.flush();
161
+ }
162
+ });
163
+ }
164
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Process-level crash handling for the structured-logging pipeline.
3
+ *
4
+ * Exceptions use `uncaughtExceptionMonitor`: Node keeps printing and exiting, so
5
+ * this never owns termination, and monitors run before any handler the agent
6
+ * installed. Rejections need a real listener — a monitor stops seeing them once
7
+ * the agent registers its own handler.
8
+ */
9
+ import type { Logger } from "log4js";
10
+ /** @internal — exported only for tests; not part of the public API. */
11
+ export declare const FALLBACK_EXIT_MS = 5000;
12
+ /** Install the crash listeners. Idempotent — registered once per process. */
13
+ export declare function installUncaughtExceptionHandlers(rootLogger: Logger): void;
14
+ //# sourceMappingURL=uncaught.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uncaught.d.ts","sourceRoot":"","sources":["../../src/structured_logging/uncaught.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOrC,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAwCrC,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAczE"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Process-level crash handling for the structured-logging pipeline.
3
+ *
4
+ * Exceptions use `uncaughtExceptionMonitor`: Node keeps printing and exiting, so
5
+ * this never owns termination, and monitors run before any handler the agent
6
+ * installed. Rejections need a real listener — a monitor stops seeing them once
7
+ * the agent registers its own handler.
8
+ */
9
+ import { ACTIVE_ROOT_LOGGER, UNCAUGHT_HANDLERS_REGISTERED, } from "./constants.js";
10
+ /** @internal — exported only for tests; not part of the public API. */
11
+ export const FALLBACK_EXIT_MS = 5000;
12
+ function currentLogger() {
13
+ return globalThis[ACTIVE_ROOT_LOGGER];
14
+ }
15
+ function toError(reason) {
16
+ if (reason instanceof Error)
17
+ return reason;
18
+ const err = new Error(String(reason), { cause: reason });
19
+ err.name = "NonErrorRejection";
20
+ return err;
21
+ }
22
+ function logCrash(err, label) {
23
+ currentLogger().error(err, `${label}: ${err.name}: ${err.message}`);
24
+ }
25
+ function exitSoon() {
26
+ if (process.stdout.writableLength === 0) {
27
+ process.exit(1);
28
+ }
29
+ else {
30
+ process.stdout.once("drain", () => process.exit(1));
31
+ }
32
+ }
33
+ function handleFatalRejection(err) {
34
+ logCrash(err, "Unhandled promise rejection");
35
+ process.stderr.write((err.stack ?? String(err)) + "\n");
36
+ // Only own termination when nothing else is listening — another listener may
37
+ // be deliberately recovering. The timer backstops exitSoon()'s drain wait.
38
+ if (process.listenerCount("unhandledRejection") <= 1) {
39
+ process.exitCode = 1;
40
+ exitSoon();
41
+ setTimeout(() => process.exit(1), FALLBACK_EXIT_MS).unref();
42
+ }
43
+ }
44
+ /** Install the crash listeners. Idempotent — registered once per process. */
45
+ export function installUncaughtExceptionHandlers(rootLogger) {
46
+ const g = globalThis;
47
+ g[ACTIVE_ROOT_LOGGER] = rootLogger;
48
+ if (g[UNCAUGHT_HANDLERS_REGISTERED])
49
+ return;
50
+ g[UNCAUGHT_HANDLERS_REGISTERED] = true;
51
+ process.on("uncaughtExceptionMonitor", (value) => {
52
+ // Typed `Error`, but Node forwards whatever was thrown.
53
+ logCrash(toError(value), "Uncaught exception");
54
+ });
55
+ process.on("unhandledRejection", (reason) => {
56
+ handleFatalRejection(toError(reason));
57
+ });
58
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Structured JSON logging for the agent runtime log capture pipeline.
3
+ *
4
+ * Emits single-line JSON records on container stdout. Fluent Bit tails the
5
+ * container log, the Lua filter derives tenant/workspace keys from pod
6
+ * metadata, and writes gzipped batches to S3. The API Gateway
7
+ * `GET /admin/api/v1/agent-logs` endpoint reads them back.
8
+ *
9
+ * Activated by calling `installStructuredLogging()` at runner startup —
10
+ * typically gated by `STRUCTURED_LOGGING=true`. When inactive, the default
11
+ * log4js root in `logger.ts` is unaffected.
12
+ *
13
+ * This module is split into focused files under `structured_logging/`:
14
+ *
15
+ * - `constants.ts` — tunables and shared identifiers (service map, byte caps,
16
+ * capture category, the `Symbol.for` write slot).
17
+ * - `env.ts` — the install-time env snapshot (`FormatterEnv`, `snapshotEnv`).
18
+ * - `serialize.ts` — the crash-proof `jsonSafeStringify` and UTF-8-aware
19
+ * `truncateUtf8` helpers.
20
+ * - `layout.ts` — `buildStructuredLayout`, the log4js layout that renders the JSON
21
+ * envelope (`StructuredJSONFormatter` in the Python port).
22
+ * - `stdio_capture.ts` — `LoggingStream` + `patchStdio`, which replace
23
+ * `process.stdout.write` / `process.stderr.write` so stray `console.log` /
24
+ * direct writes also emerge as structured-logging records tagged `source: "stdout"`
25
+ * (INFO) or `"stderr"` (WARNING). Forcing stderr to ERROR was tried in
26
+ * Python and backed out — every deprecation warning would have paged
27
+ * on-call; WARNING is more honest.
28
+ * - `install.ts` — `installStructuredLogging`, the public entry point.
29
+ * - `uncaught.ts` — logs one ERROR summary per crash: an
30
+ * `uncaughtExceptionMonitor` for exceptions, a real listener for rejections.
31
+ * Installed by `installStructuredLogging`, not exported.
32
+ *
33
+ * Mirrors `agent_engine_runner_shared/structured_logging.py`. `_unwrap_logging_stream` maps
34
+ * to the snapshot of the original `write` stashed on a `Symbol.for` slot on the
35
+ * stream itself, so re-installing routes the custom appender back to the *real*
36
+ * stdout instead of recursing through the patched write.
37
+ *
38
+ * Unlike the Python port we do not replace `process.stdout` itself — Node
39
+ * code probes `process.stdout.fd` / `.isTTY` / `.columns` aggressively and a
40
+ * full replacement breaks subprocess piping, tqdm-style progress bars, and
41
+ * grpc-internal logging. We only patch `write`, which is enough to capture
42
+ * every byte that would otherwise hit the console.
43
+ */
44
+ export { MAX_TRACEBACK_BYTES, MAX_BUFFER_BYTES, } from "./structured_logging/constants.js";
45
+ export { LoggingStream } from "./structured_logging/stdio_capture.js";
46
+ export { installStructuredLogging, type InstallStructuredLoggingArgs, } from "./structured_logging/install.js";
47
+ export { FALLBACK_EXIT_MS } from "./structured_logging/uncaught.js";
48
+ //# sourceMappingURL=structured_logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured_logging.d.ts","sourceRoot":"","sources":["../src/structured_logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EACL,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EACL,wBAAwB,EACxB,KAAK,4BAA4B,GAClC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Structured JSON logging for the agent runtime log capture pipeline.
3
+ *
4
+ * Emits single-line JSON records on container stdout. Fluent Bit tails the
5
+ * container log, the Lua filter derives tenant/workspace keys from pod
6
+ * metadata, and writes gzipped batches to S3. The API Gateway
7
+ * `GET /admin/api/v1/agent-logs` endpoint reads them back.
8
+ *
9
+ * Activated by calling `installStructuredLogging()` at runner startup —
10
+ * typically gated by `STRUCTURED_LOGGING=true`. When inactive, the default
11
+ * log4js root in `logger.ts` is unaffected.
12
+ *
13
+ * This module is split into focused files under `structured_logging/`:
14
+ *
15
+ * - `constants.ts` — tunables and shared identifiers (service map, byte caps,
16
+ * capture category, the `Symbol.for` write slot).
17
+ * - `env.ts` — the install-time env snapshot (`FormatterEnv`, `snapshotEnv`).
18
+ * - `serialize.ts` — the crash-proof `jsonSafeStringify` and UTF-8-aware
19
+ * `truncateUtf8` helpers.
20
+ * - `layout.ts` — `buildStructuredLayout`, the log4js layout that renders the JSON
21
+ * envelope (`StructuredJSONFormatter` in the Python port).
22
+ * - `stdio_capture.ts` — `LoggingStream` + `patchStdio`, which replace
23
+ * `process.stdout.write` / `process.stderr.write` so stray `console.log` /
24
+ * direct writes also emerge as structured-logging records tagged `source: "stdout"`
25
+ * (INFO) or `"stderr"` (WARNING). Forcing stderr to ERROR was tried in
26
+ * Python and backed out — every deprecation warning would have paged
27
+ * on-call; WARNING is more honest.
28
+ * - `install.ts` — `installStructuredLogging`, the public entry point.
29
+ * - `uncaught.ts` — logs one ERROR summary per crash: an
30
+ * `uncaughtExceptionMonitor` for exceptions, a real listener for rejections.
31
+ * Installed by `installStructuredLogging`, not exported.
32
+ *
33
+ * Mirrors `agent_engine_runner_shared/structured_logging.py`. `_unwrap_logging_stream` maps
34
+ * to the snapshot of the original `write` stashed on a `Symbol.for` slot on the
35
+ * stream itself, so re-installing routes the custom appender back to the *real*
36
+ * stdout instead of recursing through the patched write.
37
+ *
38
+ * Unlike the Python port we do not replace `process.stdout` itself — Node
39
+ * code probes `process.stdout.fd` / `.isTTY` / `.columns` aggressively and a
40
+ * full replacement breaks subprocess piping, tqdm-style progress bars, and
41
+ * grpc-internal logging. We only patch `write`, which is enough to capture
42
+ * every byte that would otherwise hit the console.
43
+ */
44
+ export { MAX_TRACEBACK_BYTES, MAX_BUFFER_BYTES, } from "./structured_logging/constants.js";
45
+ export { LoggingStream } from "./structured_logging/stdio_capture.js";
46
+ export { installStructuredLogging, } from "./structured_logging/install.js";
47
+ export { FALLBACK_EXIT_MS } from "./structured_logging/uncaught.js";
@@ -0,0 +1,61 @@
1
+ /**
2
+ * TLS client configuration for HTTPS connections with mTLS support.
3
+ *
4
+ * This module provides utilities for configuring fetch requests with mTLS
5
+ * (mutual TLS) when connecting to platform services over HTTPS. When TLS
6
+ * certificate paths are available via environment variables, the client will
7
+ * present its certificate to the server for authentication.
8
+ *
9
+ * Uses Undici's Agent (Node.js built-in fetch is backed by Undici) for proper
10
+ * dispatcher configuration with client certificates.
11
+ */
12
+ /** Carry the active trace across a platform RPC without recording transport. */
13
+ export declare function fetchPlatform(url: string, init: RequestInit, fetchImpl?: typeof fetch): Promise<Response>;
14
+ export declare const TLS_AGENT_CACHE_MAX_ENTRIES = 32;
15
+ /**
16
+ * Get fetch options configured for the given URL with mTLS support.
17
+ *
18
+ * If url uses HTTPS and TLS certificate environment variables are set
19
+ * (TLS_CERT_PATH, TLS_KEY_PATH, TLS_CA_CERT_PATH), returns options with
20
+ * an HTTPS agent configured for mTLS. For HTTP URLs or when certificates
21
+ * are not available, returns undefined (use default fetch behavior).
22
+ *
23
+ * The HTTPS agent is cached per base URL for connection pooling.
24
+ *
25
+ * Performance: checks the agent cache BEFORE reading certificate files to avoid
26
+ * blocking the event loop on filesystem I/O for every request. Certificate files
27
+ * are only read once per base URL when creating the agent, not on every fetch.
28
+ *
29
+ * Certificate rotation: In container mode (TLS_*_PATH), automatically detects
30
+ * cert-manager rotation by comparing file mtimes and invalidates the cached agent
31
+ * so the next request picks up renewed certificates. In VM mode (TLS_*_PEM), the
32
+ * env vars are static for the pod's lifetime, so rotation requires a pod restart.
33
+ *
34
+ * @param url - The target service URL (http:// or https://)
35
+ * @returns Fetch options with agent, or undefined for HTTP/no-TLS
36
+ * @throws Error if HTTPS is used but TLS configuration is incomplete
37
+ */
38
+ export declare function getFetchOptionsWithTLS(url: string): RequestInit | undefined;
39
+ /**
40
+ * Cleanup function to close all cached Undici agents.
41
+ * Should be called during graceful shutdown.
42
+ */
43
+ export declare function closeAllTLSAgents(): void;
44
+ /**
45
+ * Fetch options for a call that may legitimately run for minutes.
46
+ *
47
+ * Node's fetch is backed by Undici, whose default `headersTimeout` of 300s
48
+ * applies *independently* of any AbortSignal the caller passes. Since the OE
49
+ * holds `/tool/execute` open until the tool returns, response headers do not
50
+ * arrive until then — so without raising it here, a longer per-call deadline is
51
+ * silently capped at 300s and surfaces as `UND_ERR_HEADERS_TIMEOUT` rather than
52
+ * as the caller's own timeout. The connect budget stays short and is set
53
+ * explicitly rather than inherited.
54
+ *
55
+ * Applies to http:// as well as https://, since the cap is Undici's, not TLS's.
56
+ *
57
+ * @param url - The target service URL
58
+ * @param deadlineMs - The call's own deadline; headers/body budgets match it
59
+ */
60
+ export declare function getFetchOptionsForLongCall(url: string, deadlineMs: number): RequestInit;
61
+ //# sourceMappingURL=tls_client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tls_client.d.ts","sourceRoot":"","sources":["../src/tls_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH,gFAAgF;AAChF,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAcnB;AAUD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAyH9C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAwG3E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAOxC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GACjB,WAAW,CAuBb"}