Skip to content

Commit b2f4ad5

Browse files
authored
feat: Add utilities for custom views (bt custom-views push & bt custom-views preview) (#2191)
1 parent 4a79372 commit b2f4ad5

6 files changed

Lines changed: 213 additions & 0 deletions

File tree

‎.changeset/custom-view-helpers.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"braintrust": minor
3+
---
4+
5+
feat: Add utilities for custom views (push + preview)

‎js/package.json‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@
3737
"require": "./dist/index.js",
3838
"default": "./dist/index.mjs"
3939
},
40+
"./custom-views": {
41+
"types": "./dist/custom-views.d.ts",
42+
"import": "./dist/custom-views.mjs",
43+
"module": "./dist/custom-views.mjs",
44+
"require": "./dist/custom-views.js",
45+
"default": "./dist/custom-views.mjs"
46+
},
4047
"./workerd": {
4148
"import": "./dist/workerd.mjs",
4249
"require": "./dist/workerd.js",
@@ -214,6 +221,7 @@
214221
},
215222
"dependencies": {
216223
"@next/env": "^14.2.3",
224+
"@types/react": "^18.3.1",
217225
"@vercel/functions": "^1.0.2",
218226
"acorn": "^8.16.0",
219227
"acorn-import-attributes": "^1.9.5",

‎js/src/custom-views/exports.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { customDatasetView, customTraceView } from "./registry";

‎js/src/custom-views/registry.ts‎

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import type { ReactNode } from "react";
2+
3+
type SpanFieldName = "input" | "output" | "expected" | "metadata";
4+
5+
type SpanFields<
6+
TInput = unknown,
7+
TOutput = unknown,
8+
TExpected = unknown,
9+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
10+
> = {
11+
input?: TInput;
12+
output?: TOutput;
13+
expected?: TExpected;
14+
metadata?: TMetadata;
15+
};
16+
17+
type TraceViewSpan<
18+
TInput = unknown,
19+
TOutput = unknown,
20+
TExpected = unknown,
21+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
22+
> = {
23+
id: string;
24+
span_id: string;
25+
root_span_id: string;
26+
parent_span_id?: string | null;
27+
span_parents?: string[];
28+
data: {
29+
input?: TInput;
30+
output?: TOutput;
31+
expected?: TExpected;
32+
metadata?: TMetadata;
33+
scores?: Record<string, number | null>;
34+
metrics?: Record<string, number | string>;
35+
error?: string;
36+
tags?: string[];
37+
span_attributes?: Record<string, unknown>;
38+
[key: string]: unknown;
39+
};
40+
children: string[];
41+
};
42+
43+
type CustomViewUpdateTarget = "selected" | "root" | { spanId: string };
44+
45+
type CustomViewUpdateResult = {
46+
transactionId: string | null;
47+
};
48+
49+
type CustomViewSpanUpdate<
50+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
51+
> = {
52+
target?: CustomViewUpdateTarget;
53+
metadata?: Partial<TMetadata> & Record<string, unknown>;
54+
scores?: Record<string, number | null>;
55+
tags?: string[] | null;
56+
};
57+
58+
type TraceViewTrace<
59+
TInput = unknown,
60+
TOutput = unknown,
61+
TExpected = unknown,
62+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
63+
> = {
64+
rootSpanId: string;
65+
selectedSpanId: string;
66+
spanOrder: string[];
67+
spans: Record<string, TraceViewSpan<TInput, TOutput, TExpected, TMetadata>>;
68+
fetchSpanFields: (
69+
spanIds: string | string[],
70+
fields?: SpanFieldName[],
71+
) => Promise<
72+
Record<string, SpanFields<TInput, TOutput, TExpected, TMetadata>>
73+
>;
74+
update: (
75+
update: CustomViewSpanUpdate<TMetadata>,
76+
) => Promise<CustomViewUpdateResult>;
77+
};
78+
79+
type TraceViewProps<
80+
TInput = unknown,
81+
TOutput = unknown,
82+
TExpected = unknown,
83+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
84+
> = {
85+
trace: TraceViewTrace<TInput, TOutput, TExpected, TMetadata>;
86+
span: TraceViewSpan<TInput, TOutput, TExpected, TMetadata>;
87+
selectSpan?: (spanId: string) => void;
88+
update?: (field: string, value: unknown) => void;
89+
};
90+
91+
type DatasetViewProps<
92+
TInput = unknown,
93+
TExpected = unknown,
94+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
95+
> = {
96+
id: string;
97+
input?: TInput;
98+
expected?: TExpected;
99+
metadata?: TMetadata;
100+
tags?: string[];
101+
update: (update: {
102+
input?: TInput;
103+
expected?: TExpected;
104+
metadata?: Partial<TMetadata> & Record<string, unknown>;
105+
tags?: string[] | null;
106+
}) => Promise<CustomViewUpdateResult>;
107+
};
108+
109+
type Component<Props> = (props: Props) => ReactNode;
110+
111+
type ProjectRef = string | { id: string } | { name: string };
112+
type DatasetRef = { id: string } | { name: string };
113+
114+
type CustomTraceViewDefinition = {
115+
name: string;
116+
slug: string;
117+
project?: ProjectRef;
118+
};
119+
120+
type CustomTraceView<
121+
TInput = unknown,
122+
TOutput = unknown,
123+
TExpected = unknown,
124+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
125+
> = CustomTraceViewDefinition & {
126+
kind: "trace";
127+
component: Component<TraceViewProps<TInput, TOutput, TExpected, TMetadata>>;
128+
};
129+
130+
type CustomDatasetViewDefinition = {
131+
name: string;
132+
slug: string;
133+
dataset: DatasetRef;
134+
project?: ProjectRef;
135+
};
136+
137+
type CustomDatasetView<
138+
TInput = unknown,
139+
TExpected = unknown,
140+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
141+
> = CustomDatasetViewDefinition & {
142+
kind: "dataset";
143+
component: Component<DatasetViewProps<TInput, TExpected, TMetadata>>;
144+
};
145+
146+
/**
147+
* Defines a trace custom view for discovery by the `bt views` CLI.
148+
*
149+
* @experimental This API is not yet stabilized and may change across non-major versions.
150+
*/
151+
export function customTraceView<
152+
TInput = unknown,
153+
TOutput = unknown,
154+
TExpected = unknown,
155+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
156+
>(
157+
definition: CustomTraceViewDefinition,
158+
component: Component<TraceViewProps<TInput, TOutput, TExpected, TMetadata>>,
159+
): CustomTraceView<TInput, TOutput, TExpected, TMetadata> {
160+
return { ...definition, component, kind: "trace" };
161+
}
162+
163+
/**
164+
* Defines a dataset custom view for discovery by the `bt views` CLI.
165+
*
166+
* @experimental This API is not yet stabilized and may change across non-major versions.
167+
*/
168+
export function customDatasetView<
169+
TInput = unknown,
170+
TExpected = unknown,
171+
TMetadata extends Record<string, unknown> = Record<string, unknown>,
172+
>(
173+
definition: CustomDatasetViewDefinition,
174+
component: Component<DatasetViewProps<TInput, TExpected, TMetadata>>,
175+
): CustomDatasetView<TInput, TExpected, TMetadata> {
176+
return { ...definition, component, kind: "dataset" };
177+
}

‎js/tsup.config.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default defineConfig([
1414
{
1515
entry: {
1616
index: "src/node/index.ts",
17+
"custom-views": "src/custom-views/exports.ts",
1718
"apply-auto-instrumentation":
1819
"src/node/apply-auto-instrumentation-entry.ts",
1920
"vitest-evals-reporter": "src/wrappers/vitest-evals/reporter.ts",

‎pnpm-lock.yaml‎

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)