Skip to content

Commit

Permalink
Merge branch 'master' into adrian/trace_sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
adrnswanberg authored Dec 13, 2024
2 parents dfffb78 + abebaa8 commit 0a406a1
Show file tree
Hide file tree
Showing 25 changed files with 250 additions and 39 deletions.
2 changes: 1 addition & 1 deletion docs/docs/guides/evaluation/scorers.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ In Weave, Scorers are used to evaluate AI outputs and return evaluation metrics.
from weave.scorers import OpenAIModerationScorer
from openai import OpenAI

oai_client = OpenAI(api_key=...) # initialize your LLM client here
oai_client = OpenAI() # initialize your LLM client here

scorer = OpenAIModerationScorer(
client=oai_client,
Expand Down
1 change: 0 additions & 1 deletion docs/docs/guides/integrations/local_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ First and most important, is the `base_url` change during the `openai.OpenAI()`

```python
client = openai.OpenAI(
api_key='fake',
base_url="http://localhost:1234",
)
```
Expand Down
1 change: 0 additions & 1 deletion docs/docs/guides/integrations/notdiamond.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ preference_id = train_router(
response_column="actual",
language="en",
maximize=True,
api_key=api_key,
)
```

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ _In this example, we're using openai so you will need to add an OpenAI [API key]
import weave
from openai import OpenAI

client = OpenAI(api_key="...")
client = OpenAI()

# Weave will track the inputs, outputs and code of this function
# highlight-next-line
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/tutorial-tracing_2.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Building on our [basic tracing example](/quickstart), we will now add additional
import json
from openai import OpenAI

client = OpenAI(api_key="...")
client = OpenAI()

# highlight-next-line
@weave.op()
Expand Down
12 changes: 9 additions & 3 deletions tests/trace/test_evaluations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,13 +1021,19 @@ def my_second_scorer(text, output, model_output):

ds = [{"text": "hello"}]

with pytest.raises(ValueError, match="Both 'output' and 'model_output'"):
with pytest.raises(
ValueError, match="cannot include both `output` and `model_output`"
):
scorer = MyScorer()

with pytest.raises(ValueError, match="Both 'output' and 'model_output'"):
with pytest.raises(
ValueError, match="cannot include both `output` and `model_output`"
):
evaluation = weave.Evaluation(dataset=ds, scorers=[MyScorer()])

with pytest.raises(ValueError, match="Both 'output' and 'model_output'"):
with pytest.raises(
ValueError, match="cannot include both `output` and `model_output`"
):
evaluation = weave.Evaluation(dataset=ds, scorers=[my_second_scorer])


Expand Down
2 changes: 1 addition & 1 deletion weave-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"unified": "^10.1.0",
"unist-util-visit": "3.1.0",
"universal-perf-hooks": "^1.0.1",
"uuid": "^11.0.3",
"vega": "^5.24.0",
"vega-lite": "5.6.0",
"vega-tooltip": "^0.28.0",
Expand Down Expand Up @@ -236,7 +237,6 @@
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "4.7.4",
"uuid": "^11.0.3",
"vite": "5.2.9",
"vitest": "^1.6.0"
},
Expand Down
5 changes: 5 additions & 0 deletions weave-js/src/assets/icons/icon-spiral.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions weave-js/src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {datadogRum} from '@datadog/browser-rum';
import * as Sentry from '@sentry/react';
import React, {Component, ErrorInfo, ReactNode} from 'react';
import {v7 as uuidv7} from 'uuid';

import {weaveErrorToDDPayload} from '../errors';
import {ErrorPanel} from './ErrorPanel';
Expand All @@ -10,33 +11,41 @@ type Props = {
};

type State = {
hasError: boolean;
uuid: string | undefined;
timestamp: Date | undefined;
error: Error | undefined;
};

export class ErrorBoundary extends Component<Props, State> {
public static getDerivedStateFromError(_: Error): State {
return {hasError: true};
public static getDerivedStateFromError(error: Error): State {
return {uuid: uuidv7(), timestamp: new Date(), error};
}
public state: State = {
hasError: false,
uuid: undefined,
timestamp: undefined,
error: undefined,
};

public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
const {uuid} = this.state;
datadogRum.addAction(
'weave_panel_error_boundary',
weaveErrorToDDPayload(error)
weaveErrorToDDPayload(error, undefined, uuid)
);

Sentry.captureException(error, {
extra: {
uuid,
},
tags: {
weaveErrorBoundary: 'true',
},
});
}

public render() {
if (this.state.hasError) {
return <ErrorPanel />;
const {uuid, timestamp, error} = this.state;
if (error != null) {
return <ErrorPanel uuid={uuid} timestamp={timestamp} error={error} />;
}

return this.props.children;
Expand Down
105 changes: 103 additions & 2 deletions weave-js/src/components/ErrorPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import React, {forwardRef, useEffect, useRef, useState} from 'react';
import copyToClipboard from 'copy-to-clipboard';
import _ from 'lodash';
import React, {
forwardRef,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import styled from 'styled-components';

import {toast} from '../common/components/elements/Toast';
import {hexToRGB, MOON_300, MOON_600} from '../common/css/globals.styles';
import {useViewerInfo} from '../common/hooks/useViewerInfo';
import {getCookieBool, getFirebaseCookie} from '../common/util/cookie';
import {Button} from './Button';
import {Icon} from './Icon';
import {Tooltip} from './Tooltip';

Expand All @@ -14,6 +26,11 @@ type ErrorPanelProps = {
title?: string;
subtitle?: string;
subtitle2?: string;

// These props are for error details object
uuid?: string;
timestamp?: Date;
error?: Error;
};

export const Centered = styled.div`
Expand Down Expand Up @@ -85,11 +102,87 @@ export const ErrorPanelSmall = ({
);
};

const getDateObject = (timestamp?: Date): Record<string, any> | null => {
if (!timestamp) {
return null;
}
return {
// e.g. "2024-12-12T06:10:19.475Z",
iso: timestamp.toISOString(),
// e.g. "Thursday, December 12, 2024 at 6:10:19 AM Coordinated Universal Time"
long: timestamp.toLocaleString('en-US', {
weekday: 'long',
year: 'numeric', // Full year
month: 'long', // Full month name
day: 'numeric', // Day of the month
hour: 'numeric', // Hour (12-hour or 24-hour depending on locale)
minute: 'numeric',
second: 'numeric',
timeZone: 'UTC', // Ensures it's in UTC
timeZoneName: 'long', // Full time zone name
}),
user: timestamp.toLocaleString('en-US', {
dateStyle: 'full',
timeStyle: 'full',
}),
};
};

const getErrorObject = (error?: Error): Record<string, any> | null => {
if (!error) {
return null;
}

// Error object properties are not enumerable so we have to copy them manually
const stack = (error.stack ?? '').split('\n');
return {
message: error.message,
stack,
};
};

export const ErrorPanelLarge = forwardRef<HTMLDivElement, ErrorPanelProps>(
({title, subtitle, subtitle2}, ref) => {
({title, subtitle, subtitle2, uuid, timestamp, error}, ref) => {
const titleStr = title ?? DEFAULT_TITLE;
const subtitleStr = subtitle ?? DEFAULT_SUBTITLE;
const subtitle2Str = subtitle2 ?? DEFAULT_SUBTITLE2;

const {userInfo} = useViewerInfo();

const onClick = useCallback(() => {
const betaVersion = getFirebaseCookie('betaVersion');
const isUsingAdminPrivileges = getCookieBool('use_admin_privileges');
const {location, navigator, screen} = window;
const {userAgent, language} = navigator;
const details = {
uuid,
url: location.href,
error: getErrorObject(error),
timestamp_err: getDateObject(timestamp),
timestamp_copied: getDateObject(new Date()),
user: _.pick(userInfo, ['id', 'username']), // Skipping teams and admin
cookies: {
...(betaVersion && {betaVersion}),
...(isUsingAdminPrivileges && {use_admin_privileges: true}),
},
browser: {
userAgent,
language,
screenSize: {
width: screen.width,
height: screen.height,
},
viewportSize: {
width: window.innerWidth,
height: window.innerHeight,
},
},
};
const detailsText = JSON.stringify(details, null, 2);
copyToClipboard(detailsText);
toast('Copied to clipboard');
}, [uuid, timestamp, error, userInfo]);

return (
<Large ref={ref}>
<Circle $size={40} $hoverHighlight={false}>
Expand All @@ -98,6 +191,14 @@ export const ErrorPanelLarge = forwardRef<HTMLDivElement, ErrorPanelProps>(
<Title>{titleStr}</Title>
<Subtitle>{subtitleStr}</Subtitle>
<Subtitle>{subtitle2Str}</Subtitle>
<Button
style={{marginTop: 16}}
size="small"
variant="secondary"
icon="copy"
onClick={onClick}>
Copy error details
</Button>
</Large>
);
}
Expand Down
6 changes: 5 additions & 1 deletion weave-js/src/components/Form/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type TextFieldProps = {
dataTest?: string;
step?: number;
variant?: 'default' | 'ghost';
isContainerNightAware?: boolean;
};

export const TextField = ({
Expand All @@ -59,6 +60,7 @@ export const TextField = ({
autoComplete,
dataTest,
step,
isContainerNightAware,
}: TextFieldProps) => {
const textFieldSize = size ?? 'medium';
const leftPaddingForIcon = textFieldSize === 'medium' ? 'pl-34' : 'pl-36';
Expand All @@ -83,7 +85,6 @@ export const TextField = ({
<Tailwind style={{width: '100%'}}>
<div
className={classNames(
'night-aware',
'relative rounded-sm',
textFieldSize === 'medium' ? 'h-32' : 'h-40',
'bg-white dark:bg-moon-900',
Expand All @@ -93,6 +94,9 @@ export const TextField = ({
variant === 'ghost' &&
'outline outline-1 outline-transparent dark:outline-transparent',
{
// must not add "night-aware" class if already in a night-aware
// container, otherwise they'll cancel each other out
'night-aware': !isContainerNightAware,
'hover:outline-2 [&:hover:not(:focus-within)]:outline-[#83E4EB] dark:[&:hover:not(:focus-within)]:outline-teal-650':
!errorState && variant === 'default',
'focus-within:outline-2 focus-within:outline-teal-400 dark:focus-within:outline-teal-600':
Expand Down
5 changes: 5 additions & 0 deletions weave-js/src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ import {ReactComponent as ImportSmoothing} from '../../assets/icons/icon-smoothi
import {ReactComponent as ImportSort} from '../../assets/icons/icon-sort.svg';
import {ReactComponent as ImportSortAscending} from '../../assets/icons/icon-sort-ascending.svg';
import {ReactComponent as ImportSortDescending} from '../../assets/icons/icon-sort-descending.svg';
import {ReactComponent as ImportSpiral} from '../../assets/icons/icon-spiral.svg';
import {ReactComponent as ImportSplit} from '../../assets/icons/icon-split.svg';
import {ReactComponent as ImportSquare} from '../../assets/icons/icon-square.svg';
import {ReactComponent as ImportStar} from '../../assets/icons/icon-star.svg';
Expand Down Expand Up @@ -914,6 +915,9 @@ export const IconSortAscending = (props: SVGIconProps) => (
export const IconSortDescending = (props: SVGIconProps) => (
<ImportSortDescending {...updateIconProps(props)} />
);
export const IconSpiral = (props: SVGIconProps) => (
<ImportSpiral {...updateIconProps(props)} />
);
export const IconSplit = (props: SVGIconProps) => (
<ImportSplit {...updateIconProps(props)} />
);
Expand Down Expand Up @@ -1295,6 +1299,7 @@ const ICON_NAME_TO_ICON: Record<IconName, ElementType> = {
sort: IconSort,
'sort-ascending': IconSortAscending,
'sort-descending': IconSortDescending,
spiral: IconSpiral,
split: IconSplit,
square: IconSquare,
star: IconStar,
Expand Down
1 change: 1 addition & 0 deletions weave-js/src/components/Icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export {
IconSort,
IconSortAscending,
IconSortDescending,
IconSpiral,
IconSplit,
IconSquare,
IconStar,
Expand Down
1 change: 1 addition & 0 deletions weave-js/src/components/Icon/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export const IconNames = {
Sort: 'sort',
SortAscending: 'sort-ascending',
SortDescending: 'sort-descending',
Spiral: 'spiral',
Split: 'split',
Square: 'square',
Star: 'star',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export const CustomGridTreeDataGroupingCell: FC<
<Box
sx={{
width: '100%',
height: '100%',
height: '34px',
borderBottom: BORDER_STYLE,
}}></Box>
<Box sx={{width: '100%', height: '100%'}}></Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ export const ChoicesView = ({
}
if (choices.length === 1) {
return (
<ChoiceView choice={choices[0]} isStructuredOutput={isStructuredOutput} />
<ChoiceView
choice={choices[0]}
isStructuredOutput={isStructuredOutput}
choiceIndex={0}
/>
);
}
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ export const MessagePanel = ({
}
}, [message.content, contentRef?.current?.scrollHeight]);

// Set isShowingMore to true when editor is opened
useEffect(() => {
if (editorHeight !== null) {
setIsShowingMore(true);
}
}, [editorHeight]);

const isUser = message.role === 'user';
const isSystemPrompt = message.role === 'system';
const isTool = message.role === 'tool';
Expand Down
Loading

0 comments on commit 0a406a1

Please sign in to comment.