Skip to content

Commit

Permalink
lots of good stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
gtarpenning committed Oct 23, 2024
1 parent bee5c4a commit 52206c4
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,8 @@ export const browse3ContextGen = (
traceId: string,
callId: string,
path?: string | null,
tracetree?: boolean
tracetree?: boolean,
feedbackExpand?: boolean
) => {
let url = `${projectRoot(entityName, projectName)}/calls/${callId}`;
const params = new URLSearchParams();
Expand All @@ -334,6 +335,9 @@ export const browse3ContextGen = (
if (tracetree !== undefined) {
params.set(TRACETREE_PARAM, tracetree ? '1' : '0');
}
if (feedbackExpand !== undefined) {
params.set(FEEDBACK_EXPAND_PARAM, feedbackExpand ? '1' : '0');
}
if (params.toString()) {
url += '?' + params.toString();
}
Expand Down Expand Up @@ -470,7 +474,8 @@ type RouteType = {
traceId: string,
callId: string,
path?: string | null,
tracetree?: boolean
tracetree?: boolean,
feedbackExpand?: boolean
) => string;
tracesUIUrl: (entityName: string, projectName: string) => string;
callsUIUrl: (
Expand Down Expand Up @@ -528,6 +533,7 @@ const useSetSearchParam = () => {

export const PEEK_PARAM = 'peekPath';
export const TRACETREE_PARAM = 'tracetree';
export const FEEDBACK_EXPAND_PARAM = 'feedbackExpand';
export const PATH_PARAM = 'path';

export const baseContext = browse3ContextGen(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const FeedbackGrid = ({
const currentViewerId = userInfo ? userInfo.id : null;
return (
<Tailwind>
<div className="flex flex-col gap-4">stsst</div>
{paths.map(path => {
return (
<div key={path}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export const FeedbackGridInner = ({
if (params.row.feedback_type === 'wandb.reaction.1') {
return params.row.payload.emoji;
}
if (params.row.feedback_type === 'wandb.structuredFeedback.1') {
return params.row.payload.value;
}
return <CellValueString value={JSON.stringify(params.row.payload)} />;
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export const FeedbackTypeChip = ({feedbackType}: FeedbackTypeChipProps) => {
} else if (feedbackType === 'wandb.note.1') {
color = 'gold';
label = 'Note';
} else if (feedbackType === 'wandb.structuredFeedback.1') {
color = 'moon';
label = 'Structured';
}
return <Pill color={color} label={label} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import React, { SyntheticEvent, useEffect, useState } from 'react';
import { useWFHooks } from '../../pages/wfReactInterface/context';
import { useGetTraceServerClientContext } from '../../pages/wfReactInterface/traceServerClientContext';
import { LoadingDots } from '@wandb/weave/components/LoadingDots';
import ModifiedDropdown from '@wandb/weave/common/components/elements/ModifiedDropdown';
import { DropdownProps } from 'semantic-ui-react';
import Select, { StylesConfig } from 'react-select'
import Select from 'react-select'
import { Tailwind } from '@wandb/weave/components/Tailwind';
import { Checkbox } from '@mui/material';
import CreatableSelect from 'react-select/creatable';

export const StructuredFeedbackColumn = ({structuredFeedbackOptions, callId, weaveRef, entity, project}: {structuredFeedbackOptions: any, callId: string, weaveRef: string, entity: string, project: string}) => {
export const StructuredFeedbackCell = ({structuredFeedbackOptions, callId, weaveRef, entity, project, feedbackSpecRef}: {structuredFeedbackOptions: any, callId: string, weaveRef: string, entity: string, project: string, feedbackSpecRef: string}) => {

const {useFeedback} = useWFHooks();
const query = useFeedback(
Expand All @@ -19,23 +19,26 @@ export const StructuredFeedbackColumn = ({structuredFeedbackOptions, callId, wea
);

const [currentFeedbackId, setCurrentFeedbackId] = useState<string | null>(null);
const [foundValue, setFoundValue] = useState<string | null>(null);
const [foundValue, setFoundValue] = useState<string | number | null>(null);
const getTsClient = useGetTraceServerClientContext();

const onAddFeedback = (value: string, currentFeedbackId: string | null): boolean => {
const onAddFeedback = (value: any, currentFeedbackId: string | null): Promise<boolean> => {
console.log("onAddFeedback", value, currentFeedbackId);
const req = {
project_id: `${entity}/${project}`,
weave_ref: weaveRef,
creator: null,
feedback_type: 'wandb.structuredFeedback.1',
payload: {value},
payload: {
value,
ref: feedbackSpecRef,
},
sort_by: [{"created_at": "desc"}]
};
if (currentFeedbackId) {
const replaceReq = {...req, feedback_id: currentFeedbackId};
getTsClient().feedbackReplace(replaceReq).then((res) => {
console.log("feedback replaced", res);
return getTsClient().feedbackReplace(replaceReq).then((res) => {
console.log("feedback replace res", res);
if (res.reason) {
console.error("feedback replace failed", res.reason);
}
Expand All @@ -46,8 +49,8 @@ export const StructuredFeedbackColumn = ({structuredFeedbackOptions, callId, wea
return false;
});
} else {
getTsClient().feedbackCreate(req).then((res) => {
console.log("feedback created", res);
return getTsClient().feedbackCreate(req).then((res) => {
console.log("feedback create res", res);
if (res.id) {
setCurrentFeedbackId(res.id);
return true;
Expand All @@ -65,71 +68,112 @@ export const StructuredFeedbackColumn = ({structuredFeedbackOptions, callId, wea
if (!currFeedback) {
return
}
if (currFeedback.payload.ref !== feedbackSpecRef) {
return;
}
setCurrentFeedbackId(currFeedback.id);
setFoundValue(currFeedback?.payload?.value ?? null);
}, [query?.result, query?.loading, setCurrentFeedbackId, setFoundValue]);

Check warning on line 76 in weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/StructuredFeedback.tsx

View workflow job for this annotation

GitHub Actions / WeaveJS Lint and Compile

React Hook useEffect has a missing dependency: 'feedbackSpecRef'. Either include it or remove the dependency array

if (query?.loading) {
return <LoadingDots />;
}

if (!structuredFeedbackOptions.editable) {
return <div>{foundValue}</div>
}

// console.log(structuredFeedbackOptions, query?.result?.find((feedback: any) => feedback.feedback_type === 'wandb.structuredFeedback.1'))

if (structuredFeedbackOptions.type === 'RangeFeedback') {
return <RangeFeedbackColumn min={structuredFeedbackOptions.min} max={structuredFeedbackOptions.max} onAddFeedback={onAddFeedback} defaultValue={foundValue} currentFeedbackId={currentFeedbackId}/>;
return <RangeFeedbackColumn min={structuredFeedbackOptions.min} max={structuredFeedbackOptions.max} onAddFeedback={onAddFeedback} defaultValue={foundValue} currentFeedbackId={currentFeedbackId} editable={structuredFeedbackOptions.editable} />;
} else if (structuredFeedbackOptions.type === 'CategoricalFeedback') {
return <CategoricalFeedbackColumn options={structuredFeedbackOptions.options} onAddFeedback={onAddFeedback} defaultValue={foundValue} currentFeedbackId={currentFeedbackId}/>;
return <CategoricalFeedbackColumn
options={structuredFeedbackOptions.options}
onAddFeedback={onAddFeedback}
defaultValue={foundValue}
currentFeedbackId={currentFeedbackId}
multiSelect={structuredFeedbackOptions.multi_select}
addNewOption={structuredFeedbackOptions.add_new_option}
editable={structuredFeedbackOptions.editable}
/>;
} else if (structuredFeedbackOptions.type === 'BinaryFeedback') {
return <BinaryFeedbackColumn
onAddFeedback={onAddFeedback}
defaultValue={foundValue}
currentFeedbackId={currentFeedbackId}
editable={structuredFeedbackOptions.editable}
/>;
}
return <div>unknown feedback type</div>;
};


export const RangeFeedbackColumn = (
{min, max, onAddFeedback, defaultValue, currentFeedbackId}:
{min, max, onAddFeedback, defaultValue, currentFeedbackId, editable}:
{
min: number,
max: number,
onAddFeedback?: (value: string, currentFeedbackId: string | null) => boolean,
onAddFeedback?: (value: any, currentFeedbackId: string | null) => Promise<boolean>,
defaultValue: string | null,
currentFeedbackId: string | null
currentFeedbackId: string | null,
editable: boolean
}
) => {
const [value, setValue] = useState<any | null>(min);

useEffect(() => {
if (defaultValue) {
setValue(defaultValue);
}
}, [defaultValue]);

const [value, setValue] = useState(defaultValue ?? min);

const onValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
//Todo debounce this
const success = onAddFeedback?.(e.target.value, currentFeedbackId);
if (success) {
setValue(e.target.value);
}
// Todo debounce this
const val = parseInt(e.target.value);
onAddFeedback?.(val, currentFeedbackId).then((success) => {
if (success) {
setValue(val);
}
});
}

return (
<Tailwind>
<div className="flex">
<span className="text-moon-500 mr-4">{min}</span>
<input
<span className="text-moon-500 mr-4">{value}</span>
<input
type="range"
min={min}
max={max}
step={(max - min) / 100}
value={value}
step={1.0}
value={value}
onChange={onValueChange}
disabled={!editable && defaultValue != null}
/>
<span className="text-moon-500 ml-4">{max}</span>
</div>
{/* <input
type="range"
min={min}
max={max}
step={(max - min) / 100}
value={value}
onChange={onValueChange}
/> */}
</Tailwind>
);
}

export const CategoricalFeedbackColumn = ({options, onAddFeedback, defaultValue, currentFeedbackId}: {options: string[], onAddFeedback?: (value: string, currentFeedbackId: string | null) => void, defaultValue: string | null, currentFeedbackId: string | null}) => {
export const CategoricalFeedbackColumn = ({
options,
onAddFeedback,
defaultValue,
currentFeedbackId,
multiSelect,
addNewOption,
editable
}: {
options: string[],
onAddFeedback?: (value: string, currentFeedbackId: string | null) => Promise<boolean>,
defaultValue: string | null,
currentFeedbackId: string | null,
multiSelect: boolean,
addNewOption: boolean,
editable: boolean
}) => {
let foundValue = defaultValue;
if (defaultValue && !options.includes(defaultValue)) {
console.log("structured column version mismatch, option not found", defaultValue, options);
Expand All @@ -144,33 +188,76 @@ export const CategoricalFeedbackColumn = ({options, onAddFeedback, defaultValue,
}
}, [foundValue]);

const onValueChange = (e: SyntheticEvent<HTMLSelectElement>) => {
const val = (e.target as HTMLSelectElement).value;
if (val) {
setValue(val);
onAddFeedback?.(val, currentFeedbackId);
} else {
// handle delete req?
setValue(val);
onAddFeedback?.(val, currentFeedbackId);
}
const onValueChange = (newValue: any) => {
const val = newValue ? newValue.value : '';
onAddFeedback?.(val, currentFeedbackId).then((success) => {
if (success) {
setValue(val);
}
});
}

const dropdownOptions = options.map((option: string) => ({
text: option,
label: option,
value: option,
}));
dropdownOptions.push({text: '', value: ''});

const controlStyles = {
base: "border rounded-lg bg-white hover:cursor-pointer max-w-full h-10 max-h-10",
focus: "border-primary-600 ring-1 ring-primary-500",
nonFocus: "border-gray-300 hover:border-gray-400",
};

return (
<Tailwind>
<div className="flex flex-col justify-center items-center bg-moon-100">
<select onChange={onValueChange} value={value} className='w-full bg-moon-100'>
{dropdownOptions.map((option: any) => (
<option key={option.value} value={option.value}>{option.text}</option>
))}
</select>
{addNewOption === true ? (
<CreatableSelect
classNames={{
control: ({ isFocused }) =>
`isFocused ? ${controlStyles.focus} : ${controlStyles.nonFocus} ${controlStyles.base}`,
}}
isClearable
isMulti={multiSelect}
onCreateOption={(inputValue: string) => {
return {label: inputValue, value: inputValue};
}}
onChange={onValueChange}
options={dropdownOptions}
value={dropdownOptions.find(option => option.value === value)}
isDisabled={!editable && defaultValue != null}
/>
) : (
<Select
onChange={onValueChange}
options={dropdownOptions}
value={dropdownOptions.find(option => option.value === value)}
classNames={{
control: ({ isFocused }) =>
`isFocused ? ${controlStyles.focus} : ${controlStyles.nonFocus} ${controlStyles.base}`,
}}
isDisabled={!editable && defaultValue != null}
/>
)}
</div>
</Tailwind>
);
}

export const BinaryFeedbackColumn = ({onAddFeedback, defaultValue, currentFeedbackId, editable}: {onAddFeedback?: (value: string, currentFeedbackId: string | null) => Promise<boolean>, defaultValue: string | null, currentFeedbackId: string | null, editable: boolean}) => {
// Checkbox
const [value, setValue] = useState<boolean | null>(defaultValue);

const onValueChange = (e: SyntheticEvent<HTMLInputElement>) => {
const val = (e.target as HTMLInputElement).checked ? 'true' : 'false';
onAddFeedback?.(val, currentFeedbackId).then((success) => {
if (success) {
setValue(val === 'true');
}
});
}

return <Tailwind>
<Checkbox checked={value ?? false} onChange={onValueChange} disabled={!editable && defaultValue != null}/>
</Tailwind>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import React from 'react';

Check warning on line 2 in weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/StructuredFeedbackSidebar.tsx

View workflow job for this annotation

GitHub Actions / WeaveJS Lint and Compile

Run autofix to sort these imports!
import { StructuredFeedbackCell } from './StructuredFeedback';
import { CallSchema } from '../../pages/wfReactInterface/wfDataModelHooksInterface';
import { makeRefCall } from '@wandb/weave/util/refs';
import { Tailwind } from '@wandb/weave/components/Tailwind';

export default function StructuredFeedbackSidebar(
props: {
call: CallSchema,
structuredFeedbackOptions: any,
}
) {
const weaveRef = makeRefCall(props.call.entity, props.call.project, props.call.callId);
const types = props.structuredFeedbackOptions.types;

return (
<Tailwind>
{types.map((type: any) => {
return (
<div className='p-8'>
<h3>{type.name ?? type.type}</h3>
<div className='flex flex-col gap-2'>
<StructuredFeedbackCell feedbackSpecRef={props.structuredFeedbackOptions.ref} structuredFeedbackOptions={type} callId={props.call.callId} weaveRef={weaveRef} entity={props.call.entity} project={props.call.project}/>
</div>
</div>
)
})}
</Tailwind>
)
}
Loading

0 comments on commit 52206c4

Please sign in to comment.