@foam-ai/node 0.1.0-alpha.11 → 0.1.0-alpha.12

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/README.md CHANGED
@@ -646,6 +646,85 @@ The official OpenTelemetry JavaScript SDK has no in-process Profiles provider, p
646
646
  - [OpenTelemetry Profiles public alpha announcement](https://opentelemetry.io/blog/2026/profiles-alpha/)
647
647
  - [OpenTelemetry eBPF profiler](https://github.com/open-telemetry/opentelemetry-ebpf-profiler)
648
648
 
649
+ ## TODO(pcga11): Expanded data capture (http2, gRPC, DB results, messaging)
650
+
651
+ Extension points Foam is not using yet, ordered by how much new data they
652
+ unlock. All payload extraction flows through the same redaction and size
653
+ caps as HTTP network capture.
654
+
655
+ ### Database results — biggest win, zero patching
656
+
657
+ `responseHook` hands Foam the raw driver result (in memory, no extra query)
658
+ before the span ends. Each package has its own payload shape — do not
659
+ assume a shared contract: `pg` passes `{ data }`, `mysql2`
660
+ `{ queryResults }`, `mongoose` `{ response }`, `mongodb` the command
661
+ response, `cassandra-driver` only the first result page, and
662
+ `ioredis`/`redis` (v4+) use positional `(cmdName, cmdArgs, response)`
663
+ args. Also `requestHook` (pg, ioredis, oracledb) for full query/args, and
664
+ `maskStatementHook` (mysql2) to wire SQL text into Foam redaction. No
665
+ hooks: `mysql` v1, `tedious`, `memcached` — spans only. Ship as opt-in:
666
+ results are the most PII-dense payload in the system.
667
+ `enhancedDatabaseReporting` (adds bound parameter values) must likewise
668
+ stay opt-in — redaction cannot key-match values inside SQL text.
669
+
670
+ ### http2 + gRPC — currently fully dark
671
+
672
+ Node ships `http2.client.stream.*` / `http2.server.stream.*` lifecycle
673
+ channels since 24.1 (backported to 22.x), and the request-body channels
674
+ `bodyChunkSent` / `bodySent` since 24.12.0 / 22.22.1 — pin those floors in
675
+ `support.ts`, gated on the Node version (core emits these, unlike undici's
676
+ own channels). The adapter mirrors `src/network-capture/undici.ts` but the
677
+ payloads differ: Node publishes `{ stream, writev, data, encoding }` for
678
+ `bodyChunkSent` and `{ stream }` for `bodySent`, vs undici's
679
+ `{ request, chunk }` — map fields explicitly. No OTel instrumentation
680
+ exists for http2, so Foam creates the spans too. Response bodies have no
681
+ channel and the exposed `ClientHttp2Stream` is live, not replayable:
682
+ collect passively (wrap `push()` as `http.ts` does) without reading the
683
+ stream or switching it into flowing mode, or leave response capture out.
684
+ For gRPC, `instrumentation-grpc` gives spans but zero payload hooks
685
+ (only `metadataToSpanAttributes` — enable it). The http2 body chunks carry
686
+ gRPC framing, not bare protobuf: reassemble the 1-byte compression flag +
687
+ 4-byte big-endian length prefix per message, decompressing flagged
688
+ messages, before any protobuf decode — or skip framing entirely with a
689
+ custom patch of `@grpc/grpc-js` serialization.
690
+
691
+ ### Messaging and cloud payloads — hooks receive the actual message
692
+
693
+ - `kafkajs` `producerHook`/`consumerHook` receive `{ topic, message }`
694
+ (value, key, headers); `amqplib` `publishHook`/`consumeHook`
695
+ (+confirm/end variants) receive the message `content` plus
696
+ routing/options metadata — shapes differ per hook.
697
+ - `socket.io` `emitHook`/`onHook`: event payloads (covers the socket.io
698
+ slice of WebSocket traffic).
699
+ - `aws-sdk` `preRequestHook`/`responseHook`/`exceptionHook` (the latter
700
+ gets `(span, requestInfo, err)`): normalized request/response for every
701
+ AWS call. SDK v3 only.
702
+
703
+ ### Crash and shutdown capture — data we currently lose
704
+
705
+ Errors outside any span (timer callbacks, unhandled rejections, startup)
706
+ are invisible, and `beforeExit` — Foam's only lifecycle hook — does not
707
+ fire on crashes or signals, so the batch holding the spans that explain a
708
+ crash dies with the process, and every SIGTERM (each deploy) drops the
709
+ final batch window. Use `uncaughtExceptionMonitor` (never plain
710
+ `uncaughtException`, which suppresses the default crash) — but note an
711
+ async flush started there is abandoned when the process terminates, so
712
+ crash delivery needs a synchronous durable handoff (sync write to disk, or
713
+ a helper process that ships it) rather than relying on the async exporter.
714
+ SIGTERM/SIGINT get flush-then-resignal handlers with a bounded flush
715
+ timeout that never swallows the signal or changes the exit code. `warning`
716
+ events ship as logs.
717
+
718
+ ### Smaller / later
719
+
720
+ - `logHook` (bunyan/pino/winston), `graphql` `responseHook`,
721
+ `express`/`koa`/`restify` `requestHook`: enrichment, little new data.
722
+ - Channels: `worker_threads` (detect uninstrumented workers), 24+ native
723
+ `console.*` (could replace patch-based console capture),
724
+ `tracing:module.*` (library-version detection), `child_process`.
725
+ - No hook surface at all: raw `ws` frames (custom patch, frame data model)
726
+ and Prisma (Rust engine; needs app-enabled Prisma OTel tracing).
727
+
649
728
  ## TODO(pcga11): Anthropic instrumentation
650
729
 
651
730
  There is no released official OpenTelemetry JavaScript instrumentation for the Anthropic SDK yet, but one is actively in progress in js-contrib, based on the OpenInference donation from Arize. Once `@opentelemetry/instrumentation-anthropic` is released (and picked up by `auto-instrumentations-node`), bundle it here like the OpenAI and aws-sdk ones. Until then, Anthropic coverage is handled case by case with the FDE (see FDE.md). Track upstream progress:
@@ -4,7 +4,7 @@ export declare const FOAM_INGEST_HOST: string;
4
4
  export declare const ATTR_FOAM_INGEST_HOST = "foam.ingest.host";
5
5
  export declare const FOAM_IDENTIFIER_NAME = "[foam-otel]";
6
6
  export declare const FOAM_DISTRO_NAME = "@foam-ai/node";
7
- export declare const FOAM_DISTRO_VERSION = "0.1.0-alpha.11";
7
+ export declare const FOAM_DISTRO_VERSION = "0.1.0-alpha.12";
8
8
  export declare const FOAM_OTLP_TRACES_PATH = "/v1/traces";
9
9
  export declare const FOAM_OTLP_LOGS_PATH = "/v1/logs";
10
10
  export declare const FOAM_OTLP_METRICS_PATH = "/v1/metrics";
package/dist/constants.js CHANGED
@@ -7,7 +7,7 @@ exports.FOAM_INGEST_HOST = new URL(exports.FOAM_ENDPOINT).hostname;
7
7
  exports.ATTR_FOAM_INGEST_HOST = "foam.ingest.host";
8
8
  exports.FOAM_IDENTIFIER_NAME = "[foam-otel]";
9
9
  exports.FOAM_DISTRO_NAME = "@foam-ai/node";
10
- exports.FOAM_DISTRO_VERSION = "0.1.0-alpha.11";
10
+ exports.FOAM_DISTRO_VERSION = "0.1.0-alpha.12";
11
11
  exports.FOAM_OTLP_TRACES_PATH = "/v1/traces";
12
12
  exports.FOAM_OTLP_LOGS_PATH = "/v1/logs";
13
13
  exports.FOAM_OTLP_METRICS_PATH = "/v1/metrics";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foam-ai/node",
3
- "version": "0.1.0-alpha.11",
3
+ "version": "0.1.0-alpha.12",
4
4
  "description": "Foam JavaScript Node.js SDK",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {