@insightfactory.ai/insightfactory-databricks-langgraph-tracer 1.0.0-dev.0
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 +176 -0
- package/LICENSE +5 -0
- package/README.md +160 -0
- package/THIRD_PARTY_NOTICES +26 -0
- package/dist/cost.d.ts +76 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +124 -0
- package/dist/cost.js.map +1 -0
- package/dist/databricks-tracer.d.ts +235 -0
- package/dist/databricks-tracer.d.ts.map +1 -0
- package/dist/databricks-tracer.js +841 -0
- package/dist/databricks-tracer.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated-keys.d.ts +39 -0
- package/dist/generated-keys.d.ts.map +1 -0
- package/dist/generated-keys.js +39 -0
- package/dist/generated-keys.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +130 -0
- package/dist/index.js.map +1 -0
- package/dist/pricing/model-pricing-overrides.json +28 -0
- package/dist/pricing/model-pricing.json +1 -0
- package/dist/token-aggregate.d.ts +29 -0
- package/dist/token-aggregate.d.ts.map +1 -0
- package/dist/token-aggregate.js +63 -0
- package/dist/token-aggregate.js.map +1 -0
- package/dist/trace-metadata.d.ts +14 -0
- package/dist/trace-metadata.d.ts.map +1 -0
- package/dist/trace-metadata.js +33 -0
- package/dist/trace-metadata.js.map +1 -0
- package/dist/uc-export.d.ts +48 -0
- package/dist/uc-export.d.ts.map +1 -0
- package/dist/uc-export.js +243 -0
- package/dist/uc-export.js.map +1 -0
- package/package.json +68 -0
- package/src/pricing/model-pricing-overrides.json +28 -0
- package/src/pricing/model-pricing.json +1 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Enriched 5-field trace-level token rollup (base 3 + cache-read/creation + reasoning). */
|
|
2
|
+
export interface EnrichedTraceTokenUsage {
|
|
3
|
+
input_tokens: number;
|
|
4
|
+
output_tokens: number;
|
|
5
|
+
total_tokens: number;
|
|
6
|
+
cache_read_input_tokens: number;
|
|
7
|
+
cache_creation_input_tokens: number;
|
|
8
|
+
reasoning_tokens: number;
|
|
9
|
+
}
|
|
10
|
+
interface SpanLike {
|
|
11
|
+
spanId: string;
|
|
12
|
+
parentId: string | null;
|
|
13
|
+
attributes: Record<string, unknown> | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Replacement for `@mlflow/core`'s `aggregateUsageFromSpans` that returns the
|
|
17
|
+
* enriched rollup (cache-read / cache-creation / reasoning in addition to the
|
|
18
|
+
* base input/output/total sums). Reads `gen_ai.usage.input_tokens.cached`,
|
|
19
|
+
* `gen_ai.usage.input_tokens.cache_creation`, and
|
|
20
|
+
* `gen_ai.usage.output_tokens.reasoning` written by the tracer on LLM child
|
|
21
|
+
* spans. Preserves the SDK's double-count guard that skips a span whose parent
|
|
22
|
+
* also carries `TOKEN_USAGE`.
|
|
23
|
+
*
|
|
24
|
+
* Returns `null` when no span has `TOKEN_USAGE` — matching the SDK contract so
|
|
25
|
+
* the exporter's `if (aggregatedUsage)` guard still kicks in.
|
|
26
|
+
*/
|
|
27
|
+
export declare function enrichedAggregateUsageFromSpans(spans: readonly SpanLike[]): EnrichedTraceTokenUsage | null;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=token-aggregate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-aggregate.d.ts","sourceRoot":"","sources":["../src/token-aggregate.ts"],"names":[],"mappings":"AAoBA,4FAA4F;AAC5F,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,QAAQ;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CACjD;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,SAAS,QAAQ,EAAE,GACzB,uBAAuB,GAAG,IAAI,CAsChC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enriched trace-level token rollup for the `@mlflow/core` SDK aggregator.
|
|
3
|
+
*
|
|
4
|
+
* This is a TypeScript-only enrichment with no Python parallel: the Python
|
|
5
|
+
* package relies on MLflow's native aggregation of the reserved per-span
|
|
6
|
+
* `mlflow.chat.tokenUsage` (which already carries the cache slots), whereas the
|
|
7
|
+
* `@mlflow/core` SDK's built-in `aggregateUsageFromSpans` hard-codes a 3-field
|
|
8
|
+
* trace rollup (input/output/total), dropping the cache + reasoning detail. We
|
|
9
|
+
* replace it (see `patchMlflowAggregator` in `index.ts`) so the Databricks
|
|
10
|
+
* "Usage breakdown" panel renders the `(cache read)` row and so the
|
|
11
|
+
* cache-creation / reasoning counts are queryable on the trace.
|
|
12
|
+
*
|
|
13
|
+
* NB: the enriched trace-level `mlflow.trace.tokenUsage` key it feeds is NOT
|
|
14
|
+
* part of the shared cross-language schema — the schema's token keys are all
|
|
15
|
+
* span-level. This module only enriches the SDK's own trace rollup.
|
|
16
|
+
*/
|
|
17
|
+
import { SpanAttrKey } from "./generated-keys.js";
|
|
18
|
+
const TOKEN_USAGE = SpanAttrKey.TOKEN_USAGE; // "mlflow.chat.tokenUsage"
|
|
19
|
+
function toNum(v) {
|
|
20
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Replacement for `@mlflow/core`'s `aggregateUsageFromSpans` that returns the
|
|
24
|
+
* enriched rollup (cache-read / cache-creation / reasoning in addition to the
|
|
25
|
+
* base input/output/total sums). Reads `gen_ai.usage.input_tokens.cached`,
|
|
26
|
+
* `gen_ai.usage.input_tokens.cache_creation`, and
|
|
27
|
+
* `gen_ai.usage.output_tokens.reasoning` written by the tracer on LLM child
|
|
28
|
+
* spans. Preserves the SDK's double-count guard that skips a span whose parent
|
|
29
|
+
* also carries `TOKEN_USAGE`.
|
|
30
|
+
*
|
|
31
|
+
* Returns `null` when no span has `TOKEN_USAGE` — matching the SDK contract so
|
|
32
|
+
* the exporter's `if (aggregatedUsage)` guard still kicks in.
|
|
33
|
+
*/
|
|
34
|
+
export function enrichedAggregateUsageFromSpans(spans) {
|
|
35
|
+
const total = {
|
|
36
|
+
input_tokens: 0,
|
|
37
|
+
output_tokens: 0,
|
|
38
|
+
total_tokens: 0,
|
|
39
|
+
cache_read_input_tokens: 0,
|
|
40
|
+
cache_creation_input_tokens: 0,
|
|
41
|
+
reasoning_tokens: 0,
|
|
42
|
+
};
|
|
43
|
+
let hasUsage = false;
|
|
44
|
+
for (const span of spans) {
|
|
45
|
+
const tokenUsage = span.attributes?.[TOKEN_USAGE];
|
|
46
|
+
if (!tokenUsage)
|
|
47
|
+
continue;
|
|
48
|
+
if (span.parentId) {
|
|
49
|
+
const parent = spans.find((s) => s.spanId === span.parentId);
|
|
50
|
+
if (parent?.attributes?.[TOKEN_USAGE])
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
total.input_tokens += toNum(tokenUsage.input_tokens);
|
|
54
|
+
total.output_tokens += toNum(tokenUsage.output_tokens);
|
|
55
|
+
total.total_tokens += toNum(tokenUsage.total_tokens);
|
|
56
|
+
total.cache_read_input_tokens += toNum(span.attributes?.[SpanAttrKey.INPUT_TOKENS_CACHED]);
|
|
57
|
+
total.cache_creation_input_tokens += toNum(span.attributes?.[SpanAttrKey.INPUT_TOKENS_CACHE_CREATION]);
|
|
58
|
+
total.reasoning_tokens += toNum(span.attributes?.[SpanAttrKey.OUTPUT_TOKENS_REASONING]);
|
|
59
|
+
hasUsage = true;
|
|
60
|
+
}
|
|
61
|
+
return hasUsage ? total : null;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=token-aggregate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-aggregate.js","sourceRoot":"","sources":["../src/token-aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,2BAA2B;AAkBxE,SAAS,KAAK,CAAC,CAAU;IACvB,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,+BAA+B,CAC7C,KAA0B;IAE1B,MAAM,KAAK,GAA4B;QACrC,YAAY,EAAE,CAAC;QACf,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,uBAAuB,EAAE,CAAC;QAC1B,2BAA2B,EAAE,CAAC;QAC9B,gBAAgB,EAAE,CAAC;KACpB,CAAC;IACF,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,WAAW,CAEnC,CAAC;QACd,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7D,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC,WAAW,CAAC;gBAAE,SAAS;QAClD,CAAC;QAED,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACrD,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QACvD,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QACrD,KAAK,CAAC,uBAAuB,IAAI,KAAK,CACpC,IAAI,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,mBAAmB,CAAC,CACnD,CAAC;QACF,KAAK,CAAC,2BAA2B,IAAI,KAAK,CACxC,IAAI,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAC3D,CAAC;QACF,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAC7B,IAAI,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,uBAAuB,CAAC,CACvD,CAAC;QACF,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes trace-level `tags` and/or `traceMetadata` on the in-memory trace for
|
|
3
|
+
* `traceId`. Both objects are mutated in place via `Object.assign` — writes must
|
|
4
|
+
* happen before the SDK flushes the trace to the exporter (the span processor
|
|
5
|
+
* pops the trace from the manager synchronously when the root span ends).
|
|
6
|
+
*
|
|
7
|
+
* Failures (missing trace, unexpected shape, etc.) are swallowed: the tracer
|
|
8
|
+
* must never throw from this path (resilient by design).
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeTraceFields(traceId: string, fields: {
|
|
11
|
+
tags?: Record<string, string>;
|
|
12
|
+
metadata?: Record<string, string>;
|
|
13
|
+
}): void;
|
|
14
|
+
//# sourceMappingURL=trace-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-metadata.d.ts","sourceRoot":"","sources":["../src/trace-metadata.ts"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3E,IAAI,CASN"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Deliberate private-API wrapper around `@mlflow/core`'s `InMemoryTraceManager`.
|
|
2
|
+
// `updateCurrentTrace` is a no-op from `startSpan`-style tracers (it keys off the
|
|
3
|
+
// OTEL active span, which is not set when callers pass `parent` explicitly), so
|
|
4
|
+
// trace-level tag/metadata writes have to reach into the in-memory manager. This
|
|
5
|
+
// is the TypeScript parallel to the Python tracer's `_write_trace_fields`
|
|
6
|
+
// (`InMemoryTraceManager.get_trace(trace_id)` + `.info.tags`/`.info.trace_metadata`
|
|
7
|
+
// mutation). Centralized here so the rest of the tracer never imports from
|
|
8
|
+
// `@mlflow/core/dist/...` paths directly.
|
|
9
|
+
import { InMemoryTraceManager } from "@mlflow/core/dist/core/trace_manager.js";
|
|
10
|
+
/**
|
|
11
|
+
* Writes trace-level `tags` and/or `traceMetadata` on the in-memory trace for
|
|
12
|
+
* `traceId`. Both objects are mutated in place via `Object.assign` — writes must
|
|
13
|
+
* happen before the SDK flushes the trace to the exporter (the span processor
|
|
14
|
+
* pops the trace from the manager synchronously when the root span ends).
|
|
15
|
+
*
|
|
16
|
+
* Failures (missing trace, unexpected shape, etc.) are swallowed: the tracer
|
|
17
|
+
* must never throw from this path (resilient by design).
|
|
18
|
+
*/
|
|
19
|
+
export function writeTraceFields(traceId, fields) {
|
|
20
|
+
try {
|
|
21
|
+
const trace = InMemoryTraceManager.getInstance().getTrace(traceId);
|
|
22
|
+
if (!trace)
|
|
23
|
+
return;
|
|
24
|
+
if (fields.tags)
|
|
25
|
+
Object.assign(trace.info.tags, fields.tags);
|
|
26
|
+
if (fields.metadata)
|
|
27
|
+
Object.assign(trace.info.traceMetadata, fields.metadata);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// never throw from a live run
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=trace-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-metadata.js","sourceRoot":"","sources":["../src/trace-metadata.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,kFAAkF;AAClF,gFAAgF;AAChF,iFAAiF;AACjF,0EAA0E;AAC1E,oFAAoF;AACpF,2EAA2E;AAC3E,0CAA0C;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/E;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,MAA4E;IAE5E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,oBAAoB,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,MAAM,CAAC,IAAI;YAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Experiment tag carrying the UC destination (`catalog.schema.table_prefix`). */
|
|
2
|
+
export declare const UC_DESTINATION_TAG = "mlflow.experiment.databricksTraceDestinationPath";
|
|
3
|
+
/** Experiment tag naming the spans table outright (preferred over deriving). */
|
|
4
|
+
export declare const UC_SPANS_TABLE_TAG = "mlflow.experiment.databricksTraceSpanStorageTable";
|
|
5
|
+
/** Header naming the UC spans table for the OTLP ingest endpoint. */
|
|
6
|
+
export declare const UC_TABLE_HEADER = "X-Databricks-UC-Table-Name";
|
|
7
|
+
export interface UcDestination {
|
|
8
|
+
catalogName: string;
|
|
9
|
+
schemaName: string;
|
|
10
|
+
tablePrefix: string;
|
|
11
|
+
/** `catalog.schema.table_prefix` — the V4 location path segment. */
|
|
12
|
+
fullTablePrefix: string;
|
|
13
|
+
/** `catalog.schema.<prefix>_otel_spans` — the OTLP ingest header value. */
|
|
14
|
+
spansTableName: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse a `databricksTraceDestinationPath` tag value into a {@link UcDestination}.
|
|
18
|
+
* Throws when the value is not the expected three-part `catalog.schema.prefix`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseUcDestinationPath(path: string): UcDestination;
|
|
21
|
+
type HeadersProvider = () => Promise<Record<string, string>> | Record<string, string>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch the experiment and resolve its UC destination from the
|
|
24
|
+
* `databricksTraceDestinationPath` tag. Returns `null` for classic
|
|
25
|
+
* (workspace-backed) experiments. SDK/network failures raise an actionable
|
|
26
|
+
* configuration error rather than a generic fetch failure, mirroring the
|
|
27
|
+
* Python package's hardened guard.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveUcDestination(hostUrl: string, headersProvider: HeadersProvider, experimentId: string): Promise<UcDestination | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Databricks' OTLP ingest rejects batches over 10 MiB ("Batch exceeds maximum
|
|
32
|
+
* size of 10485760 bytes"). Stay comfortably under it — protobuf framing per
|
|
33
|
+
* chunk adds a little over the sum of span sizes.
|
|
34
|
+
*/
|
|
35
|
+
export declare const OTLP_MAX_BATCH_BYTES: number;
|
|
36
|
+
/** Reset patch state. For testing only. */
|
|
37
|
+
export declare function _resetUcExportForTests(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Patch `MlflowSpanExporter.exportTraceToBackend` with a UC-aware
|
|
40
|
+
* implementation. The destination is resolved once (memoized promise) from
|
|
41
|
+
* the experiment's tags on the first export — the SDK's client (and its
|
|
42
|
+
* auth headers) only exists at export time — and classic experiments
|
|
43
|
+
* delegate to the original implementation untouched. Resolution failures
|
|
44
|
+
* log loudly and fall back to classic export rather than dropping traces.
|
|
45
|
+
*/
|
|
46
|
+
export declare function patchExporterForUc(experimentId: string): void;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=uc-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-export.d.ts","sourceRoot":"","sources":["../src/uc-export.ts"],"names":[],"mappings":"AAiCA,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,qDAAqD,CAAC;AAErF,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,sDAAsD,CAAC;AAEtF,qEAAqE;AACrE,eAAO,MAAM,eAAe,+BAA+B,CAAC;AAM5D,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAgBlE;AAED,KAAK,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAsCtF;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+B/B;AAOD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAkB,CAAC;AAsGpD,2CAA2C;AAC3C,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAsD7D"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UC table-backed span export for Databricks MLflow experiments.
|
|
3
|
+
*
|
|
4
|
+
* `@mlflow/core@0.2.0` exports traces via `StartTraceV3` + artifact-store
|
|
5
|
+
* upload — a path UC table-backed experiments silently ignore (the calls
|
|
6
|
+
* succeed but the spans never reach the `<prefix>_otel_spans` Delta table and
|
|
7
|
+
* V4 `search_traces` returns nothing). This module mirrors the Python
|
|
8
|
+
* package's UC fix (mlflow_utils.py `_resolve_uc_trace_location`) plus the
|
|
9
|
+
* protocol MLflow >= 3.10 Python uses natively:
|
|
10
|
+
*
|
|
11
|
+
* - Spans: OTLP `ExportTraceServiceRequest` protobuf POSTed to
|
|
12
|
+
* `/api/2.0/otel/v1/traces` with the `X-Databricks-UC-Table-Name` header
|
|
13
|
+
* naming the fully-qualified `<catalog>.<schema>.<prefix>_otel_spans` table.
|
|
14
|
+
* - Trace info: `CreateTraceInfo` JSON POSTed to
|
|
15
|
+
* `/api/4.0/mlflow/traces/<location>/<otelTraceId>/info` with a
|
|
16
|
+
* `UC_TABLE_PREFIX` trace location and `mlflow.trace_schema.version = "4"`.
|
|
17
|
+
*
|
|
18
|
+
* Like the aggregator patch in `index.ts`, the seam is a `createRequire`
|
|
19
|
+
* monkeypatch of the SDK's `MlflowSpanExporter` — the exporter pops the trace
|
|
20
|
+
* from `InMemoryTraceManager` synchronously inside root-span `end()`, so
|
|
21
|
+
* there is no public post-export hook to intercept instead.
|
|
22
|
+
*
|
|
23
|
+
* UC detection is resolved lazily (and memoized) from the experiment's
|
|
24
|
+
* `databricksTraceDestinationPath` tag on the first export, because the
|
|
25
|
+
* public `initDatabricksTracing` surface is synchronous and the SDK's
|
|
26
|
+
* authenticated client only exists at export time. Experiments without the
|
|
27
|
+
* tag fall through to the SDK's classic export path unchanged.
|
|
28
|
+
*/
|
|
29
|
+
import { createRequire } from "node:module";
|
|
30
|
+
import { ProtobufTraceSerializer } from "@opentelemetry/otlp-transformer";
|
|
31
|
+
import { DatabricksTracingConfigurationError } from "./errors.js";
|
|
32
|
+
/** Experiment tag carrying the UC destination (`catalog.schema.table_prefix`). */
|
|
33
|
+
export const UC_DESTINATION_TAG = "mlflow.experiment.databricksTraceDestinationPath";
|
|
34
|
+
/** Experiment tag naming the spans table outright (preferred over deriving). */
|
|
35
|
+
export const UC_SPANS_TABLE_TAG = "mlflow.experiment.databricksTraceSpanStorageTable";
|
|
36
|
+
/** Header naming the UC spans table for the OTLP ingest endpoint. */
|
|
37
|
+
export const UC_TABLE_HEADER = "X-Databricks-UC-Table-Name";
|
|
38
|
+
/** V4 schema version stamped into UC trace metadata. */
|
|
39
|
+
const TRACE_SCHEMA_VERSION_KEY = "mlflow.trace_schema.version";
|
|
40
|
+
const UC_TRACE_SCHEMA_VERSION = "4";
|
|
41
|
+
/**
|
|
42
|
+
* Parse a `databricksTraceDestinationPath` tag value into a {@link UcDestination}.
|
|
43
|
+
* Throws when the value is not the expected three-part `catalog.schema.prefix`.
|
|
44
|
+
*/
|
|
45
|
+
export function parseUcDestinationPath(path) {
|
|
46
|
+
const parts = path.split(".");
|
|
47
|
+
const [catalogName, schemaName, tablePrefix] = parts;
|
|
48
|
+
if (parts.length !== 3 || !catalogName || !schemaName || !tablePrefix) {
|
|
49
|
+
throw new DatabricksTracingConfigurationError(`Unexpected ${UC_DESTINATION_TAG} value '${path}' ` +
|
|
50
|
+
"(expected 'catalog.schema.table_prefix').");
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
catalogName,
|
|
54
|
+
schemaName,
|
|
55
|
+
tablePrefix,
|
|
56
|
+
fullTablePrefix: path,
|
|
57
|
+
spansTableName: `${catalogName}.${schemaName}.${tablePrefix}_otel_spans`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Fetch the experiment and resolve its UC destination from the
|
|
62
|
+
* `databricksTraceDestinationPath` tag. Returns `null` for classic
|
|
63
|
+
* (workspace-backed) experiments. SDK/network failures raise an actionable
|
|
64
|
+
* configuration error rather than a generic fetch failure, mirroring the
|
|
65
|
+
* Python package's hardened guard.
|
|
66
|
+
*/
|
|
67
|
+
export async function resolveUcDestination(hostUrl, headersProvider, experimentId) {
|
|
68
|
+
const url = `${hostUrl.replace(/\/$/, "")}/api/2.0/mlflow/experiments/get?experiment_id=${encodeURIComponent(experimentId)}`;
|
|
69
|
+
let response;
|
|
70
|
+
try {
|
|
71
|
+
response = await fetch(url, { headers: await headersProvider() });
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
throw new DatabricksTracingConfigurationError(`Failed to fetch experiment '${experimentId}' while resolving the UC trace ` +
|
|
75
|
+
`destination: ${err.message}`);
|
|
76
|
+
}
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new DatabricksTracingConfigurationError(`Failed to fetch experiment '${experimentId}' while resolving the UC trace ` +
|
|
79
|
+
`destination: HTTP ${response.status}`);
|
|
80
|
+
}
|
|
81
|
+
const body = (await response.json());
|
|
82
|
+
const tags = body.experiment?.tags ?? [];
|
|
83
|
+
const destinationTag = tags.find((t) => t.key === UC_DESTINATION_TAG);
|
|
84
|
+
if (!destinationTag?.value)
|
|
85
|
+
return null;
|
|
86
|
+
const destination = parseUcDestinationPath(destinationTag.value);
|
|
87
|
+
// Prefer the explicit spans-table tag when present; the derived
|
|
88
|
+
// `<prefix>_otel_spans` name is the documented default fallback.
|
|
89
|
+
const spansTableTag = tags.find((t) => t.key === UC_SPANS_TABLE_TAG);
|
|
90
|
+
if (spansTableTag?.value) {
|
|
91
|
+
destination.spansTableName = spansTableTag.value;
|
|
92
|
+
}
|
|
93
|
+
return destination;
|
|
94
|
+
}
|
|
95
|
+
/** Strip the `tr-` prefix from an MLflow trace id, yielding the OTel hex id. */
|
|
96
|
+
function toOtelTraceId(mlflowTraceId) {
|
|
97
|
+
return mlflowTraceId.startsWith("tr-") ? mlflowTraceId.slice(3) : mlflowTraceId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Databricks' OTLP ingest rejects batches over 10 MiB ("Batch exceeds maximum
|
|
101
|
+
* size of 10485760 bytes"). Stay comfortably under it — protobuf framing per
|
|
102
|
+
* chunk adds a little over the sum of span sizes.
|
|
103
|
+
*/
|
|
104
|
+
export const OTLP_MAX_BATCH_BYTES = 9 * 1024 * 1024;
|
|
105
|
+
/**
|
|
106
|
+
* POST one OTLP `ExportTraceServiceRequest` to the Databricks ingest endpoint,
|
|
107
|
+
* addressed at the UC spans table.
|
|
108
|
+
*/
|
|
109
|
+
async function postOtlpBatch(client, destination, payload) {
|
|
110
|
+
const url = `${client.hostUrl.replace(/\/$/, "")}/api/2.0/otel/v1/traces`;
|
|
111
|
+
const response = await fetch(url, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: {
|
|
114
|
+
...(await client.headersProvider()),
|
|
115
|
+
"Content-Type": "application/x-protobuf",
|
|
116
|
+
[UC_TABLE_HEADER]: destination.spansTableName,
|
|
117
|
+
},
|
|
118
|
+
body: payload,
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const text = await response.text().catch(() => "");
|
|
122
|
+
throw new Error(`OTLP span export failed: HTTP ${response.status} ${text.slice(0, 500)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* POST the trace's spans to the Databricks OTLP ingest endpoint, splitting
|
|
127
|
+
* into multiple requests when the serialized batch exceeds the ingest size
|
|
128
|
+
* cap (SQL-heavy agent turns routinely serialize past 10 MiB — one validation
|
|
129
|
+
* run saw a 98-span turn produce a 16.8 MB batch).
|
|
130
|
+
* Spans are append-only rows in the UC table, so a trace's spans may arrive
|
|
131
|
+
* across several requests. Binary-splits recursively (log N serializations);
|
|
132
|
+
* a single span that alone exceeds the cap is sent anyway and surfaces the
|
|
133
|
+
* server's 400 — truncating span payloads is the tracer's job, not the
|
|
134
|
+
* exporter's.
|
|
135
|
+
*/
|
|
136
|
+
async function exportSpansToUcTable(client, destination, spans, maxBatchBytes = OTLP_MAX_BATCH_BYTES) {
|
|
137
|
+
if (spans.length === 0)
|
|
138
|
+
return;
|
|
139
|
+
const payload = ProtobufTraceSerializer.serializeRequest(spans);
|
|
140
|
+
if (!payload) {
|
|
141
|
+
throw new Error("OTLP serialization produced no payload");
|
|
142
|
+
}
|
|
143
|
+
if (payload.byteLength > maxBatchBytes && spans.length > 1) {
|
|
144
|
+
const mid = Math.ceil(spans.length / 2);
|
|
145
|
+
await exportSpansToUcTable(client, destination, spans.slice(0, mid), maxBatchBytes);
|
|
146
|
+
await exportSpansToUcTable(client, destination, spans.slice(mid), maxBatchBytes);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
await postOtlpBatch(client, destination, payload);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* POST the trace info to the V4 `CreateTraceInfo` endpoint with a
|
|
153
|
+
* `UC_TABLE_PREFIX` location and V4 trace-id format
|
|
154
|
+
* (`trace:/<location>/<otelTraceId>`).
|
|
155
|
+
*/
|
|
156
|
+
async function exportTraceInfoV4(client, destination, info) {
|
|
157
|
+
const otelTraceId = toOtelTraceId(info.traceId);
|
|
158
|
+
const body = info.toJson();
|
|
159
|
+
body.trace_id = `trace:/${destination.fullTablePrefix}/${otelTraceId}`;
|
|
160
|
+
body.trace_location = {
|
|
161
|
+
type: "UC_TABLE_PREFIX",
|
|
162
|
+
uc_table_prefix: {
|
|
163
|
+
catalog_name: destination.catalogName,
|
|
164
|
+
schema_name: destination.schemaName,
|
|
165
|
+
table_prefix: destination.tablePrefix,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
body.trace_metadata = {
|
|
169
|
+
...body.trace_metadata,
|
|
170
|
+
[TRACE_SCHEMA_VERSION_KEY]: UC_TRACE_SCHEMA_VERSION,
|
|
171
|
+
};
|
|
172
|
+
const url = `${client.hostUrl.replace(/\/$/, "")}/api/4.0/mlflow/traces/` +
|
|
173
|
+
`${destination.fullTablePrefix}/${otelTraceId}/info`;
|
|
174
|
+
const response = await fetch(url, {
|
|
175
|
+
method: "POST",
|
|
176
|
+
headers: {
|
|
177
|
+
...(await client.headersProvider()),
|
|
178
|
+
"Content-Type": "application/json",
|
|
179
|
+
},
|
|
180
|
+
body: JSON.stringify(body),
|
|
181
|
+
});
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
const text = await response.text().catch(() => "");
|
|
184
|
+
throw new Error(`V4 trace-info export failed: HTTP ${response.status} ${text.slice(0, 500)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
let exporterPatched = false;
|
|
188
|
+
/** Reset patch state. For testing only. */
|
|
189
|
+
export function _resetUcExportForTests() {
|
|
190
|
+
exporterPatched = false;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Patch `MlflowSpanExporter.exportTraceToBackend` with a UC-aware
|
|
194
|
+
* implementation. The destination is resolved once (memoized promise) from
|
|
195
|
+
* the experiment's tags on the first export — the SDK's client (and its
|
|
196
|
+
* auth headers) only exists at export time — and classic experiments
|
|
197
|
+
* delegate to the original implementation untouched. Resolution failures
|
|
198
|
+
* log loudly and fall back to classic export rather than dropping traces.
|
|
199
|
+
*/
|
|
200
|
+
export function patchExporterForUc(experimentId) {
|
|
201
|
+
if (exporterPatched)
|
|
202
|
+
return;
|
|
203
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
204
|
+
const exporterModule = nodeRequire("@mlflow/core/dist/exporters/mlflow.js");
|
|
205
|
+
const proto = exporterModule.MlflowSpanExporter.prototype;
|
|
206
|
+
const originalExport = proto.exportTraceToBackend;
|
|
207
|
+
let destinationPromise = null;
|
|
208
|
+
const resolveOnce = (client) => {
|
|
209
|
+
destinationPromise ??= resolveUcDestination(client.hostUrl, client.headersProvider, experimentId).catch((err) => {
|
|
210
|
+
console.error("[databricks-langgraph-tracer] UC destination resolution failed:", err);
|
|
211
|
+
return null;
|
|
212
|
+
});
|
|
213
|
+
return destinationPromise;
|
|
214
|
+
};
|
|
215
|
+
proto.exportTraceToBackend = async function (trace) {
|
|
216
|
+
const destination = await resolveOnce(this._client);
|
|
217
|
+
if (!destination) {
|
|
218
|
+
return originalExport.call(this, trace);
|
|
219
|
+
}
|
|
220
|
+
// UC path: OTLP spans -> UC table; trace info -> V4 endpoint. No
|
|
221
|
+
// artifact upload (UC experiments do not read the artifact store).
|
|
222
|
+
// Span export goes first — trace info without spans renders as an
|
|
223
|
+
// empty trace, while spans without info are recoverable on retry.
|
|
224
|
+
const spans = trace.data.spans.map((s) => s._span);
|
|
225
|
+
try {
|
|
226
|
+
await exportSpansToUcTable(this._client, destination, spans);
|
|
227
|
+
await exportTraceInfoV4(this._client, destination, trace.info);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
console.error(`[databricks-langgraph-tracer] UC export failed for ${trace.info.traceId}, ` +
|
|
231
|
+
"falling back to classic export:", err);
|
|
232
|
+
return originalExport.call(this, trace);
|
|
233
|
+
}
|
|
234
|
+
// Mirror the SDK's `finally` cleanup: `export()` records this promise in
|
|
235
|
+
// `_pendingExports` and the original implementation deletes the entry on
|
|
236
|
+
// completion. Only the UC success path needs this here — both delegation
|
|
237
|
+
// paths above end in `originalExport`, whose own `finally` cleans up
|
|
238
|
+
// (deleting earlier would hide an in-flight fallback from `forceFlush`).
|
|
239
|
+
delete this._pendingExports[trace.info.traceId];
|
|
240
|
+
};
|
|
241
|
+
exporterPatched = true;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=uc-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uc-export.js","sourceRoot":"","sources":["../src/uc-export.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@insightfactory.ai/insightfactory-databricks-langgraph-tracer",
|
|
3
|
+
"version": "1.0.0-dev.0",
|
|
4
|
+
"description": "LangGraph tracing for Databricks MLflow (TypeScript)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"packageManager": "yarn@4.12.0",
|
|
7
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "insightfactory.ai",
|
|
10
|
+
"email": "support@insightfactory.ai"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://insightfactory.ai",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"databricks",
|
|
15
|
+
"langchain",
|
|
16
|
+
"langgraph",
|
|
17
|
+
"mlflow",
|
|
18
|
+
"tracing"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"registry": "https://registry.npmjs.org/",
|
|
25
|
+
"access": "public",
|
|
26
|
+
"provenance": true
|
|
27
|
+
},
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"src/pricing",
|
|
39
|
+
"CHANGELOG.md",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"THIRD_PARTY_NOTICES",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.build.json && node scripts/copy-pricing.mjs",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"keys:generate": "tsx scripts/generate-keys.ts",
|
|
48
|
+
"keys:check": "tsx scripts/generate-keys.ts --check",
|
|
49
|
+
"pricing:update": "tsx scripts/update-pricing.ts"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@opentelemetry/otlp-transformer": "^0.205.0",
|
|
53
|
+
"@opentelemetry/sdk-trace-base": "^2.1.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@langchain/core": "^1.1.47",
|
|
57
|
+
"@mlflow/core": "^0.2.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@langchain/core": "^1.1.47",
|
|
61
|
+
"@langchain/langgraph": "^1.2.6",
|
|
62
|
+
"@mlflow/core": "^0.2.0",
|
|
63
|
+
"@types/node": "^25.5.0",
|
|
64
|
+
"tsx": "^4.21.0",
|
|
65
|
+
"typescript": "^6.0.2",
|
|
66
|
+
"vitest": "^4.1.4"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"azure_ai/deepseek-v4-flash": {
|
|
3
|
+
"input_cost_per_token": 1.9e-7,
|
|
4
|
+
"output_cost_per_token": 5.1e-7,
|
|
5
|
+
"litellm_provider": "azure_ai",
|
|
6
|
+
"max_input_tokens": 131072,
|
|
7
|
+
"max_output_tokens": 131072,
|
|
8
|
+
"max_tokens": 131072,
|
|
9
|
+
"mode": "chat",
|
|
10
|
+
"supports_function_calling": true,
|
|
11
|
+
"supports_reasoning": true,
|
|
12
|
+
"supports_tool_choice": true,
|
|
13
|
+
"source": "https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/introducing-deepseek-v4-flash-and-v4-pro-in-microsoft-foundry/4515174"
|
|
14
|
+
},
|
|
15
|
+
"azure_ai/deepseek-v4-pro": {
|
|
16
|
+
"input_cost_per_token": 1.74e-6,
|
|
17
|
+
"output_cost_per_token": 3.48e-6,
|
|
18
|
+
"litellm_provider": "azure_ai",
|
|
19
|
+
"max_input_tokens": 131072,
|
|
20
|
+
"max_output_tokens": 131072,
|
|
21
|
+
"max_tokens": 131072,
|
|
22
|
+
"mode": "chat",
|
|
23
|
+
"supports_function_calling": true,
|
|
24
|
+
"supports_reasoning": true,
|
|
25
|
+
"supports_tool_choice": true,
|
|
26
|
+
"source": "https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/introducing-deepseek-v4-flash-and-v4-pro-in-microsoft-foundry/4515174"
|
|
27
|
+
}
|
|
28
|
+
}
|