@insightfactory.ai/insightfactory-databricks-langgraph-tracer 1.0.0-dev.11 → 1.0.0-dev.15

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 (2) hide show
  1. package/README.md +73 -77
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @insightfactory.ai/insightfactory-databricks-langgraph-tracer
2
2
 
3
- LangGraph tracer for Databricks MLflow (TypeScript). It uses a custom `@mlflow/core`
3
+ LangGraph tracer for Databricks MLflow, in TypeScript. It uses a custom `@mlflow/core`
4
4
  `BaseTracer` to write trace fields, token usage, and a cost rollup on the live trace before
5
5
  the root span ends.
6
6
 
@@ -13,7 +13,7 @@ yarn add @insightfactory.ai/insightfactory-databricks-langgraph-tracer
13
13
  # or: npm install @insightfactory.ai/insightfactory-databricks-langgraph-tracer
14
14
  ```
15
15
 
16
- ESM-only. Install the runtime peer dependencies alongside it: `@langchain/core`,
16
+ ESM-only. Install the runtime peer dependencies alongside it: `@langchain/core` and
17
17
  `@mlflow/core`.
18
18
 
19
19
  ## Quickstart
@@ -33,40 +33,38 @@ await graph.invoke(state, { callbacks: getTracingCallbacks() });
33
33
 
34
34
  ## Configuration
35
35
 
36
- Env-first; `InitOptions` override the matching env var.
36
+ Environment variables are read first. `InitOptions` override the matching variable.
37
37
 
38
38
  | Setting | Env var | Notes |
39
39
  |---------|---------|-------|
40
- | Tracking URI | `MLFLOW_TRACKING_URI` | `databricks` or `databricks://<profile>` (required) |
41
- | Experiment | `MLFLOW_EXPERIMENT_ID` | by **id** only (required) |
42
- | Source tag | | `source` option, default `langgraph` |
43
- | Multimodal refs | | inline image/PDF/file bytes are externalized to a reference; `contentRefResolver` chooses it see below |
44
- | Text cap | `DATABRICKS_TRACING_MAX_STRING_CHARS` | opt-in; `maxStringChars` truncates over-long plain-text span content see below |
45
- | Disable | `TESTING` / `BUILDING` = `true`, or `enabled: false` | no-op the only non-throwing path |
46
-
47
- Missing required config **throws** `DatabricksTracingConfigurationError` (fail-fast) disable
48
- explicitly for local/dev runs. `initDatabricksTracing` is idempotent (repeat calls return the
49
- same configuration).
50
-
51
- ### Multimodal inputs (image / PDF / file)
52
-
53
- Chat-model spans record their inputs as **structured messages**, preserving the
54
- multimodal content parts a graph sends to the model OpenAI / LangChain
55
- `image_url`, OpenAI `file`, and Anthropic `image` / `document`.
56
-
57
- The inline base64 of each such part is **never stored** in the trace: it is removed
58
- before recording and replaced with a lightweight reference, so the Unity Catalog
59
- trace tables stay readable (multi-MB data URIs previously pushed large invoice
60
- traces past the SQL inline read limit). A remote `http(s)://` image URL
61
- is already a small reference, so this step keeps it verbatim (but see the text cap
62
- below if enabled, it still truncates *any* string over its threshold, URLs
63
- included). The transform runs on a copy of the inputs, so the live message sent to
64
- the model is untouched and prompt caching is unaffected.
65
-
66
- By default a part becomes a `{ type: ..., _omitted: true, bytes: N }` placeholder.
67
- To store a meaningful reference instead e.g. the Unity Catalog volume path the
68
- image was loaded from, so it can be re-fetched at runtime — pass a
69
- `contentRefResolver`:
40
+ | Tracking URI | `MLFLOW_TRACKING_URI` | `databricks` or `databricks://<profile>`. Required. |
41
+ | Experiment | `MLFLOW_EXPERIMENT_ID` | By id only. Required. |
42
+ | Source tag | none | `source` option, default `langgraph` |
43
+ | Multimodal refs | none | Inline image, PDF and file bytes become a reference. `contentRefResolver` chooses it. See below. |
44
+ | Text cap | `DATABRICKS_TRACING_MAX_STRING_CHARS` | Opt-in. `maxStringChars` truncates long plain-text span content. See below. |
45
+ | Disable | `TESTING` or `BUILDING` set to `true`, or `enabled: false` | Turns the tracer into a no-op. This is the only path that does not throw. |
46
+
47
+ Missing required config throws `DatabricksTracingConfigurationError` at startup. Disable the
48
+ tracer explicitly for local and dev runs. `initDatabricksTracing` is idempotent. Repeat calls
49
+ return the same configuration.
50
+
51
+ ### Multimodal inputs (image, PDF, file)
52
+
53
+ Chat-model spans record their inputs as structured messages, so the multimodal content
54
+ parts a graph sends to the model survive: OpenAI and LangChain `image_url`, OpenAI `file`,
55
+ and Anthropic `image` and `document`.
56
+
57
+ The inline base64 of each such part is never stored in the trace. The tracer removes it
58
+ before recording and replaces it with a small reference, so the Unity Catalog trace tables
59
+ stay readable. Multi-MB data URIs used to push large invoice traces past the SQL inline read
60
+ limit. A remote `http(s)://` image URL is already a small reference, so this step keeps it
61
+ verbatim. The text cap below, if enabled, still truncates any string over its threshold,
62
+ URLs included. The transform runs on a copy of the inputs, so the live message sent to the
63
+ model is untouched and prompt caching is unaffected.
64
+
65
+ By default a part becomes a `{ type: ..., _omitted: true, bytes: N }` placeholder. To store
66
+ a meaningful reference instead, such as the Unity Catalog volume path the image was loaded
67
+ from so it can be re-fetched later, pass a `contentRefResolver`:
70
68
 
71
69
  ```ts
72
70
  import {
@@ -75,7 +73,7 @@ import {
75
73
  } from "@insightfactory.ai/insightfactory-databricks-langgraph-tracer";
76
74
 
77
75
  const imageRef = (part: Record<string, unknown>, ctx: ContentPartContext) => {
78
- // ctx.metadata is the run metadata pass per-run data (e.g. a source volume
76
+ // ctx.metadata is the run metadata. Pass per-run data (e.g. a source volume
79
77
  // path) via the invoke config's `metadata`, which propagates to the LLM run.
80
78
  const path = ctx.metadata.encoded_images_path;
81
79
  return typeof path === "string"
@@ -86,65 +84,63 @@ const imageRef = (part: Record<string, unknown>, ctx: ContentPartContext) => {
86
84
  initDatabricksTracing({ experimentId: "...", contentRefResolver: imageRef });
87
85
  ```
88
86
 
89
- The resolver is called once per multimodal part with the part and a
90
- `ContentPartContext` `index` (position within the message content array, i.e. the
91
- page number for a one-image-per-page invoice), `bytes` (the inline payload length),
92
- and the run `metadata`. Return an object to store as the reference, or
93
- `undefined` / `null` for the default placeholder. It is also accepted by
94
- `new DatabricksLangGraphTracer({ contentRefResolver })` for per-graph wiring.
95
-
96
- The library guarantees no inline image bytes are stored: if a resolver result
97
- re-introduces an inline payload (a `data:` URI, a recognized base64 content part, or
98
- the part's own payload echoed back under any key anywhere in the returned object),
99
- it is rejected and the placeholder is used. Beyond that, keep the reference
100
- **compact** a *fabricated* large string under a custom key is the consumer's
101
- responsibility (the library strips inline payloads but does not otherwise bound what
102
- a resolver returns).
103
- `ctx.metadata` is a shallow copy of the run metadata, so a resolver cannot corrupt run
104
- state by setting top-level keys (don't mutate its nested values, which are shared).
87
+ The tracer calls the resolver once per multimodal part with the part and a
88
+ `ContentPartContext`. The context carries `index`, the part's position in the message
89
+ content array, which for a one-image-per-page invoice is the page number. It also carries
90
+ `bytes`, the inline payload length, and the run `metadata`. Return an object to store as the
91
+ reference, or `undefined` or `null` for the default placeholder.
92
+ `new DatabricksLangGraphTracer({ contentRefResolver })` also accepts it for per-graph wiring.
93
+
94
+ No inline image bytes ever reach the trace. If a resolver result re-introduces an inline
95
+ payload anywhere in the returned object, whether a `data:` URI, a recognized base64 content
96
+ part, or the part's own payload echoed back under another key, the tracer rejects it and
97
+ uses the placeholder. Beyond that, keep the reference small. The library strips inline
98
+ payloads but does not otherwise bound what a resolver returns, so a fabricated large string
99
+ under a custom key is the caller's problem. `ctx.metadata` is a shallow copy of the run
100
+ metadata, so setting top-level keys in the resolver cannot corrupt run state. Its nested
101
+ values are shared, so don't mutate those.
105
102
 
106
103
  ### Capping large text
107
104
 
108
- Multimodal externalization handles inline *bytes*, but large **plain text** can also
109
- push a trace past the SQL inline read limit — e.g. a classification vocabulary or
110
- aggregated result set threaded through every fan-out span's inputs and outputs. Set
111
- `maxStringChars` (or `DATABRICKS_TRACING_MAX_STRING_CHARS`) to truncate it:
105
+ Multimodal externalization handles inline bytes, but large plain text can also push a trace
106
+ past the SQL inline read limit. A classification vocabulary or an aggregated result set
107
+ threaded through every fan-out span's inputs and outputs is enough. Set `maxStringChars`,
108
+ or `DATABRICKS_TRACING_MAX_STRING_CHARS`, to truncate it:
112
109
 
113
110
  ```ts
114
111
  initDatabricksTracing({ experimentId: "...", maxStringChars: 50_000 });
115
112
  ```
116
113
 
117
- When set, any string **value** longer than the threshold in a span's inputs *or*
118
- outputs — is replaced with a compact placeholder:
114
+ When set, any string value longer than the threshold in a span's inputs or outputs is
115
+ replaced with a placeholder:
119
116
 
120
117
  ```json
121
- { "_truncated": true, "chars": 812345, "bytes": 812345, "preview": "first 256 chars" }
118
+ { "_truncated": true, "chars": 812345, "bytes": 812345, "preview": "<the first 256 chars>" }
122
119
  ```
123
120
 
124
- It is **opt-in / off by default** (generic truncation costs debuggability, so you
125
- choose the threshold). It caps string values only never keys or structural fields
126
- and runs on a copy, so the live messages are untouched. Also accepted by
127
- `new DatabricksLangGraphTracer({ maxStringChars })` for per-graph wiring.
128
-
129
- This is a **distinct** knob from the multimodal handling above: `contentRefResolver`
130
- chooses references for inline image/PDF/file bytes; `maxStringChars` caps arbitrary
131
- text (and never truncates a resolver's reference). Because it is generic, it also
132
- truncates any other over-threshold string — including a remote `http(s)://` image URL
133
- the multimodal step keeps verbatim so set the threshold comfortably above your
134
- reference / URL lengths. Note it is a **per-leaf** mitigation, not a hard per-trace
135
- byte budget enough sub-threshold leaves can still sum past the limit so for the
136
- heaviest spans also reduce what you record (pass ids/references through node state
137
- rather than full payloads).
138
-
139
- The threshold counts **characters** (UTF-16 units here; the Python package counts
140
- code points, so the two can differ on non-BMP text), while the inline limit is in
141
- bytes multibyte text can be up to ~4× larger in bytes than characters, so for
142
- CJK/emoji-heavy content size the cap below `limit / 4`. The placeholder's `bytes`
121
+ The cap is off by default. Generic truncation costs debuggability, so you choose the
122
+ threshold. It caps string values only, never keys or structural fields, and runs on a copy,
123
+ so the live messages are untouched. `new DatabricksLangGraphTracer({ maxStringChars })` also
124
+ accepts it for per-graph wiring.
125
+
126
+ This is a separate knob from the multimodal handling above. `contentRefResolver` chooses
127
+ references for inline image, PDF and file bytes. `maxStringChars` caps arbitrary text and
128
+ never truncates a resolver's reference. Because it is generic, it also truncates any other
129
+ string over the threshold, including a remote `http(s)://` image URL the multimodal step
130
+ keeps verbatim, so set the threshold well above your reference and URL lengths. It is a
131
+ per-leaf limit, not a per-trace byte budget. Enough sub-threshold leaves can still sum past
132
+ the limit, so for the heaviest spans also record less. Pass ids or references through node
133
+ state rather than full payloads.
134
+
135
+ The threshold counts characters. This package counts UTF-16 units and the Python package
136
+ counts code points, so the two can differ on non-BMP text. The inline limit is in bytes, and
137
+ multibyte text can be up to four times larger in bytes than in characters, so for CJK or
138
+ emoji-heavy content size the cap below a quarter of the limit. The placeholder's `bytes`
143
139
  field always reports the exact UTF-8 size of the original.
144
140
 
145
141
  ## Development
146
142
 
147
- Built and tested with **Yarn 4**:
143
+ Built and tested with Yarn 4:
148
144
 
149
145
  ```bash
150
146
  cd typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insightfactory.ai/insightfactory-databricks-langgraph-tracer",
3
- "version": "1.0.0-dev.11",
3
+ "version": "1.0.0-dev.15",
4
4
  "description": "LangGraph tracing for Databricks MLflow (TypeScript)",
5
5
  "type": "module",
6
6
  "packageManager": "yarn@4.12.0",