@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,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"}
|