diff --git a/package.json b/package.json
index 01fd446..8cc220c 100644
--- a/package.json
+++ b/package.json
@@ -25,8 +25,10 @@
"@apidevtools/json-schema-ref-parser": "^10.1.0",
"@babel/preset-typescript": "^7.22.5",
"@babel/standalone": "^7.22.9",
+ "@chakra-ui/anatomy": "^2.2.0",
"@chakra-ui/next-js": "^2.1.4",
"@chakra-ui/react": "^2.7.1",
+ "@chakra-ui/styled-system": "^2.9.1",
"@emotion/react": "^11.11.1",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.0",
@@ -63,7 +65,7 @@
"next-auth": "^4.22.1",
"next-query-params": "^4.2.3",
"nextjs-routes": "^2.0.1",
- "openai": "4.0.0-beta.2",
+ "openai": "4.0.0-beta.7",
"pluralize": "^8.0.0",
"posthog-js": "^1.68.4",
"prettier": "^3.0.0",
@@ -72,6 +74,7 @@
"react-diff-viewer": "^3.1.1",
"react-dom": "18.2.0",
"react-icons": "^4.10.1",
+ "react-json-tree": "^0.18.0",
"react-select": "^5.7.4",
"react-syntax-highlighter": "^15.5.0",
"react-textarea-autosize": "^8.5.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 98ccc43..336c987 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -17,12 +17,18 @@ dependencies:
'@babel/standalone':
specifier: ^7.22.9
version: 7.22.9
+ '@chakra-ui/anatomy':
+ specifier: ^2.2.0
+ version: 2.2.0
'@chakra-ui/next-js':
specifier: ^2.1.4
version: 2.1.4(@chakra-ui/react@2.7.1)(@emotion/react@11.11.1)(next@13.4.2)(react@18.2.0)
'@chakra-ui/react':
specifier: ^2.7.1
version: 2.7.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.6)(framer-motion@10.12.17)(react-dom@18.2.0)(react@18.2.0)
+ '@chakra-ui/styled-system':
+ specifier: ^2.9.1
+ version: 2.9.1
'@emotion/react':
specifier: ^11.11.1
version: 11.11.1(@types/react@18.2.6)(react@18.2.0)
@@ -132,8 +138,8 @@ dependencies:
specifier: ^2.0.1
version: 2.0.1(next@13.4.2)
openai:
- specifier: 4.0.0-beta.2
- version: 4.0.0-beta.2
+ specifier: 4.0.0-beta.7
+ version: 4.0.0-beta.7
pluralize:
specifier: ^8.0.0
version: 8.0.0
@@ -158,6 +164,9 @@ dependencies:
react-icons:
specifier: ^4.10.1
version: 4.10.1(react@18.2.0)
+ react-json-tree:
+ specifier: ^0.18.0
+ version: 0.18.0(@types/react@18.2.6)(react@18.2.0)
react-select:
specifier: ^5.7.4
version: 5.7.4(@types/react@18.2.6)(react-dom@18.2.0)(react@18.2.0)
@@ -686,6 +695,10 @@ packages:
resolution: {integrity: sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==}
dev: false
+ /@chakra-ui/anatomy@2.2.0:
+ resolution: {integrity: sha512-cD8Ms5C8+dFda0LrORMdxiFhAZwOIY1BSlCadz6/mHUIgNdQy13AHPrXiq6qWdMslqVHq10k5zH7xMPLt6kjFg==}
+ dev: false
+
/@chakra-ui/avatar@2.2.11(@chakra-ui/system@2.5.8)(react@18.2.0):
resolution: {integrity: sha512-CJFkoWvlCTDJTUBrKA/aVyG5Zz6TBEIVmmsJtqC6VcQuVDTxkWod8ruXnjb0LT2DUveL7xR5qZM9a5IXcsH3zg==}
peerDependencies:
@@ -2831,6 +2844,10 @@ packages:
'@babel/types': 7.22.5
dev: true
+ /@types/base16@1.0.2:
+ resolution: {integrity: sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==}
+ dev: false
+
/@types/body-parser@1.19.2:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies:
@@ -3013,6 +3030,7 @@ packages:
/@types/qs@6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
+ dev: true
/@types/range-parser@1.2.4:
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
@@ -3658,6 +3676,10 @@ packages:
resolution: {integrity: sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==}
dev: false
+ /base16@1.0.0:
+ resolution: {integrity: sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==}
+ dev: false
+
/base64-js@0.0.8:
resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
engines: {node: '>= 0.4'}
@@ -3916,10 +3938,24 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ /color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+ dev: false
+
/color2k@2.0.2:
resolution: {integrity: sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==}
dev: false
+ /color@3.2.1:
+ resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
+ dependencies:
+ color-convert: 1.9.3
+ color-string: 1.9.1
+ dev: false
+
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -5536,6 +5572,10 @@ packages:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: false
+ /is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+ dev: false
+
/is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
dependencies:
@@ -5910,6 +5950,10 @@ packages:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: false
+ /lodash.curry@4.1.1:
+ resolution: {integrity: sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==}
+ dev: false
+
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
@@ -6387,19 +6431,17 @@ packages:
is-wsl: 2.2.0
dev: true
- /openai@4.0.0-beta.2:
- resolution: {integrity: sha512-zTuAxBFe5nSO7LngbV+/O0udtgHWfXb2lFei8/sDY4GB5cOdnrRoSOtiyUfV65ANdvlI4F75oYZX7w067cxj3w==}
+ /openai@4.0.0-beta.7:
+ resolution: {integrity: sha512-jHjwvpMuGkNxiQ3erwLZsOvPEhcVrMtwtfNeYmGCjhbdB+oStVw/7pIhIPkualu8rlhLwgMR7awknIaN3IQcOA==}
dependencies:
'@types/node': 18.16.0
'@types/node-fetch': 2.6.4
- '@types/qs': 6.9.7
abort-controller: 3.0.0
agentkeepalive: 4.3.0
digest-fetch: 1.3.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.6.12
- qs: 6.11.2
transitivePeerDependencies:
- encoding
- supports-color
@@ -6832,13 +6874,6 @@ packages:
side-channel: 1.0.4
dev: false
- /qs@6.11.2:
- resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
- engines: {node: '>=0.6'}
- dependencies:
- side-channel: 1.0.4
- dev: false
-
/queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true
@@ -6875,6 +6910,18 @@ packages:
webpack: 5.88.2
dev: true
+ /react-base16-styling@0.9.1:
+ resolution: {integrity: sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==}
+ dependencies:
+ '@babel/runtime': 7.22.6
+ '@types/base16': 1.0.2
+ '@types/lodash': 4.14.195
+ base16: 1.0.0
+ color: 3.2.1
+ csstype: 3.1.2
+ lodash.curry: 4.1.1
+ dev: false
+
/react-clientside-effect@1.2.6(react@18.2.0):
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
peerDependencies:
@@ -6949,6 +6996,19 @@ packages:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: true
+ /react-json-tree@0.18.0(@types/react@18.2.6)(react@18.2.0):
+ resolution: {integrity: sha512-Qe6HKSXrr++n9Y31nkRJ3XvQMATISpqigH1vEKhLwB56+nk5thTP0ITThpjxY6ZG/ubpVq/aEHIcyLP/OPHxeA==}
+ peerDependencies:
+ '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ dependencies:
+ '@babel/runtime': 7.22.6
+ '@types/lodash': 4.14.195
+ '@types/react': 18.2.6
+ react: 18.2.0
+ react-base16-styling: 0.9.1
+ dev: false
+
/react-remove-scroll-bar@2.3.4(@types/react@18.2.6)(react@18.2.0):
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
engines: {node: '>=10'}
@@ -7360,6 +7420,12 @@ packages:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
+ /simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+ dependencies:
+ is-arrayish: 0.3.2
+ dev: false
+
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
diff --git a/src/components/OutputsTable/OutputCell/CellContent.tsx b/src/components/OutputsTable/OutputCell/CellContent.tsx
deleted file mode 100644
index 98b2388..0000000
--- a/src/components/OutputsTable/OutputCell/CellContent.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { type StackProps, VStack } from "@chakra-ui/react";
-import { CellOptions } from "./CellOptions";
-
-export const CellContent = ({
- hardRefetch,
- hardRefetching,
- children,
- ...props
-}: {
- hardRefetch: () => void;
- hardRefetching: boolean;
-} & StackProps) => (
-
-
-
- {children}
-
-
-);
diff --git a/src/components/OutputsTable/OutputCell/CellOptions.tsx b/src/components/OutputsTable/OutputCell/CellOptions.tsx
deleted file mode 100644
index dfdd139..0000000
--- a/src/components/OutputsTable/OutputCell/CellOptions.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Button, HStack, Icon, Spinner, Tooltip } from "@chakra-ui/react";
-import { BsArrowClockwise } from "react-icons/bs";
-import { useExperimentAccess } from "~/utils/hooks";
-
-export const CellOptions = ({
- refetchingOutput,
- refetchOutput,
-}: {
- refetchingOutput: boolean;
- refetchOutput: () => void;
-}) => {
- const { canModify } = useExperimentAccess();
- return (
-
- {canModify && (
-
-
-
- )}
-
- );
-};
diff --git a/src/components/OutputsTable/OutputCell/OutputCell.tsx b/src/components/OutputsTable/OutputCell/OutputCell.tsx
index c9f9f93..63b8adf 100644
--- a/src/components/OutputsTable/OutputCell/OutputCell.tsx
+++ b/src/components/OutputsTable/OutputCell/OutputCell.tsx
@@ -1,17 +1,17 @@
import { api } from "~/utils/api";
import { type PromptVariant, type Scenario } from "../types";
-import { Text, VStack } from "@chakra-ui/react";
+import { type StackProps, Text, VStack } from "@chakra-ui/react";
import { useExperiment, useHandledAsyncCallback } from "~/utils/hooks";
import SyntaxHighlighter from "react-syntax-highlighter";
import { docco } from "react-syntax-highlighter/dist/cjs/styles/hljs";
import stringify from "json-stringify-pretty-compact";
-import { type ReactElement, useState, useEffect, Fragment } from "react";
+import { type ReactElement, useState, useEffect, Fragment, useCallback } from "react";
import useSocket from "~/utils/useSocket";
import { OutputStats } from "./OutputStats";
import { RetryCountdown } from "./RetryCountdown";
import frontendModelProviders from "~/modelProviders/frontendModelProviders";
import { ResponseLog } from "./ResponseLog";
-import { CellContent } from "./CellContent";
+import { CellOptions } from "./TopActions";
const WAITING_MESSAGE_INTERVAL = 20000;
@@ -72,37 +72,49 @@ export default function OutputCell({
// TODO: disconnect from socket if we're not streaming anymore
const streamedMessage = useSocket(cell?.id);
+ const mostRecentResponse = cell?.modelResponses[cell.modelResponses.length - 1];
+
+ const CellWrapper = useCallback(
+ ({ children, ...props }: StackProps) => (
+
+ {cell && (
+
+ )}
+
+ {children}
+
+ {mostRecentResponse && (
+
+ )}
+
+ ),
+ [hardRefetching, hardRefetch, mostRecentResponse, scenario],
+ );
+
if (!vars) return null;
if (!cell && !fetchingOutput)
return (
-
+
Error retrieving output
-
+
);
if (cell && cell.errorMessage) {
return (
-
+
{cell.errorMessage}
-
+
);
}
if (disabledReason) return {disabledReason};
- const mostRecentResponse = cell?.modelResponses[cell.modelResponses.length - 1];
const showLogs = !streamedMessage && !mostRecentResponse?.output;
if (showLogs)
return (
-
+
{cell?.jobQueuedAt && }
{cell?.jobStartedAt && }
{cell?.modelResponses?.map((response) => {
@@ -124,9 +136,11 @@ export default function OutputCell({
Array.from({ length: numWaitingMessages }, (_, i) => (
@@ -146,7 +160,7 @@ export default function OutputCell({
{mostRecentResponse?.retryTime && (
)}
-
+
);
const normalizedOutput = mostRecentResponse?.output
@@ -157,50 +171,27 @@ export default function OutputCell({
if (mostRecentResponse?.output && normalizedOutput?.type === "json") {
return (
-
-
+
-
- {stringify(normalizedOutput.value, { maxLength: 40 })}
-
-
-
-
+ {stringify(normalizedOutput.value, { maxLength: 40 })}
+
+
);
}
const contentToDisplay = (normalizedOutput?.type === "text" && normalizedOutput.value) || "";
return (
-
-
-
- {contentToDisplay}
-
-
- {mostRecentResponse?.output && (
-
- )}
-
+
+ {contentToDisplay}
+
);
}
diff --git a/src/components/OutputsTable/OutputCell/PromptModal.tsx b/src/components/OutputsTable/OutputCell/PromptModal.tsx
new file mode 100644
index 0000000..18beb61
--- /dev/null
+++ b/src/components/OutputsTable/OutputCell/PromptModal.tsx
@@ -0,0 +1,36 @@
+import {
+ Modal,
+ ModalBody,
+ ModalCloseButton,
+ ModalContent,
+ ModalHeader,
+ ModalOverlay,
+ type UseDisclosureReturn,
+} from "@chakra-ui/react";
+import { type RouterOutputs } from "~/utils/api";
+import { JSONTree } from "react-json-tree";
+
+export default function ExpandedModal(props: {
+ cell: NonNullable;
+ disclosure: UseDisclosureReturn;
+}) {
+ return (
+
+
+
+ Prompt
+
+
+ true}
+ getItemString={() => ""}
+ hideRoot
+ />
+
+
+
+ );
+}
diff --git a/src/components/OutputsTable/OutputCell/TopActions.tsx b/src/components/OutputsTable/OutputCell/TopActions.tsx
new file mode 100644
index 0000000..b018e6c
--- /dev/null
+++ b/src/components/OutputsTable/OutputCell/TopActions.tsx
@@ -0,0 +1,53 @@
+import { HStack, Icon, IconButton, Spinner, Tooltip, useDisclosure } from "@chakra-ui/react";
+import { BsArrowClockwise, BsInfoCircle } from "react-icons/bs";
+import { useExperimentAccess } from "~/utils/hooks";
+import ExpandedModal from "./PromptModal";
+import { type RouterOutputs } from "~/utils/api";
+
+export const CellOptions = ({
+ cell,
+ refetchingOutput,
+ refetchOutput,
+}: {
+ cell: RouterOutputs["scenarioVariantCells"]["get"];
+ refetchingOutput: boolean;
+ refetchOutput: () => void;
+}) => {
+ const { canModify } = useExperimentAccess();
+
+ const modalDisclosure = useDisclosure();
+
+ return (
+
+ {cell && (
+ <>
+
+ }
+ onClick={modalDisclosure.onOpen}
+ size="xs"
+ colorScheme="gray"
+ color="gray.500"
+ variant="ghost"
+ />
+
+
+ >
+ )}
+ {canModify && (
+
+ }
+ />
+
+ )}
+
+ );
+};
diff --git a/src/components/OutputsTable/ScenarioEditor.tsx b/src/components/OutputsTable/ScenarioEditor.tsx
index 9f4bf88..5329118 100644
--- a/src/components/OutputsTable/ScenarioEditor.tsx
+++ b/src/components/OutputsTable/ScenarioEditor.tsx
@@ -1,9 +1,8 @@
-import { useEffect, type DragEvent } from "react";
-import { api } from "~/utils/api";
import { isEqual } from "lodash-es";
-import { type Scenario } from "./types";
+import { useEffect, useState, type DragEvent } from "react";
+import { api } from "~/utils/api";
import { useExperiment, useExperimentAccess, useHandledAsyncCallback } from "~/utils/hooks";
-import { useState } from "react";
+import { type Scenario } from "./types";
import {
Box,
@@ -12,14 +11,12 @@ import {
Icon,
IconButton,
Spinner,
- Stack,
+ Text,
Tooltip,
VStack,
- Text,
} from "@chakra-ui/react";
-import { cellPadding } from "../constants";
import { BsArrowsAngleExpand, BsX } from "react-icons/bs";
-import { RiDraggable } from "react-icons/ri";
+import { cellPadding } from "../constants";
import { FloatingLabelInput } from "./FloatingLabelInput";
import { ScenarioEditorModal } from "./ScenarioEditorModal";
@@ -115,60 +112,44 @@ export default function ScenarioEditor({
onDrop={onReorder}
backgroundColor={isDragTarget ? "gray.100" : "transparent"}
>
- {canModify && props.canHide && (
-
-
- {/* for some reason the tooltip can't position itself properly relative to the icon without the wrapping box */}
-
-
-
-
- )}
-
{variableLabels.length === 0 ? (
{vars.data ? "No scenario variables configured" : "Loading..."}
) : (
-
- Scenario
- }
- onClick={() => setScenarioEditorModalOpen(true)}
- boxSize={6}
- borderRadius={4}
- p={1.5}
- minW={0}
- colorScheme="gray"
- color="gray.500"
- variant="ghost"
- />
+
+ Scenario
+
+ }
+ onClick={() => setScenarioEditorModalOpen(true)}
+ size="xs"
+ colorScheme="gray"
+ color="gray.500"
+ variant="ghost"
+ />
+
+ {canModify && props.canHide && (
+
+
+ }
+ onClick={onHide}
+ size="xs"
+ display="flex"
+ colorScheme="gray"
+ color="gray.500"
+ variant="ghost"
+ />
+
+ )}
{variableLabels.map((key) => {
const value = values[key] ?? "";
diff --git a/src/components/OutputsTable/ScenarioEditorModal.tsx b/src/components/OutputsTable/ScenarioEditorModal.tsx
index dc8cfcb..dec1bd7 100644
--- a/src/components/OutputsTable/ScenarioEditorModal.tsx
+++ b/src/components/OutputsTable/ScenarioEditorModal.tsx
@@ -1,7 +1,6 @@
import {
Button,
HStack,
- Icon,
Modal,
ModalBody,
ModalCloseButton,
@@ -14,7 +13,6 @@ import {
VStack,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
-import { BsFileTextFill } from "react-icons/bs";
import { isEqual } from "lodash-es";
import { api } from "~/utils/api";
@@ -60,8 +58,6 @@ export const ScenarioEditorModal = ({
await utils.scenarios.list.invalidate();
}, [mutation, values]);
- console.log("scenario", scenario);
-
const vars = api.templateVars.list.useQuery({ experimentId: experiment.data?.id ?? "" });
const variableLabels = vars.data?.map((v) => v.label) ?? [];
@@ -73,12 +69,7 @@ export const ScenarioEditorModal = ({
>
-
-
-
- Scenario
-
-
+
diff --git a/src/components/OutputsTable/ScenarioRow.tsx b/src/components/OutputsTable/ScenarioRow.tsx
index d9544ce..41b4fcf 100644
--- a/src/components/OutputsTable/ScenarioRow.tsx
+++ b/src/components/OutputsTable/ScenarioRow.tsx
@@ -1,6 +1,5 @@
-import { Box, GridItem } from "@chakra-ui/react";
+import { GridItem } from "@chakra-ui/react";
import React, { useState } from "react";
-import { cellPadding } from "../constants";
import OutputCell from "./OutputCell/OutputCell";
import ScenarioEditor from "./ScenarioEditor";
import type { PromptVariant, Scenario } from "./types";
@@ -39,9 +38,7 @@ const ScenarioRow = (props: {
colStart={i + 2}
{...borders}
>
-
-
-
+
))}
>
diff --git a/src/modelProviders/openai-ChatCompletion/getCompletion.ts b/src/modelProviders/openai-ChatCompletion/getCompletion.ts
index 79ec75b..462f2fa 100644
--- a/src/modelProviders/openai-ChatCompletion/getCompletion.ts
+++ b/src/modelProviders/openai-ChatCompletion/getCompletion.ts
@@ -6,7 +6,7 @@ import {
} from "openai/resources/chat";
import { countOpenAIChatTokens } from "~/utils/countTokens";
import { type CompletionResponse } from "../types";
-import { omit } from "lodash-es";
+import { isArray, isString, omit } from "lodash-es";
import { openai } from "~/server/utils/openai";
import { truthyFilter } from "~/utils/utils";
import { APIError } from "openai";
@@ -40,6 +40,8 @@ const mergeStreamedChunks = (
((choice.delta.function_call.arguments as string) ?? "");
}
} else {
+ // @ts-expect-error the types are correctly telling us that finish_reason
+ // could be null, but don't want to fix it right now.
choices.push({ ...omit(choice, "delta"), message: { role: "assistant", ...choice.delta } });
}
}
@@ -64,6 +66,7 @@ export async function getCompletion(
try {
if (onStream) {
+ console.log("got started");
const resp = await openai.chat.completions.create(
{ ...input, stream: true },
{
@@ -71,9 +74,11 @@ export async function getCompletion(
},
);
for await (const part of resp) {
+ console.log("got part", part);
finalCompletion = mergeStreamedChunks(finalCompletion, part);
onStream(finalCompletion);
}
+ console.log("got final", finalCompletion);
if (!finalCompletion) {
return {
type: "error",
@@ -121,9 +126,17 @@ export async function getCompletion(
};
} catch (error: unknown) {
if (error instanceof APIError) {
+ // The types from the sdk are wrong
+ const rawMessage = error.message as string | string[];
+ // If the message is not a string, stringify it
+ const message = isString(rawMessage)
+ ? rawMessage
+ : isArray(rawMessage)
+ ? rawMessage.map((m) => m.toString()).join("\n")
+ : (rawMessage as any).toString();
return {
type: "error",
- message: error.message,
+ message,
autoRetry: error.status === 429 || error.status === 503,
statusCode: error.status,
};
diff --git a/src/pages/api/experiments/og-image.tsx b/src/pages/api/experiments/og-image.tsx
index 5246dcd..55f7687 100644
--- a/src/pages/api/experiments/og-image.tsx
+++ b/src/pages/api/experiments/og-image.tsx
@@ -9,7 +9,7 @@ const inconsolataRegularFontP = fetch(
new URL("../../../../public/fonts/Inconsolata_SemiExpanded-Medium.ttf", import.meta.url),
).then((res) => res.arrayBuffer());
-const OgImage = async (req: NextApiRequest, res: NextApiResponse) => {
+const OgImage = async (req: NextApiRequest, _res: NextApiResponse) => {
// @ts-expect-error - nextUrl is not defined on NextApiRequest for some reason
const searchParams = req.nextUrl?.searchParams as URLSearchParams;
const experimentLabel = searchParams.get("experimentLabel");
diff --git a/src/pages/world-champs/signup.tsx b/src/pages/world-champs/signup.tsx
index cc01888..5a94ee3 100644
--- a/src/pages/world-champs/signup.tsx
+++ b/src/pages/world-champs/signup.tsx
@@ -44,7 +44,7 @@ const TopNavbar = () => (
// Shows how long until the competition starts. Refreshes every second
function CountdownTimer(props: { date: Date } & TextProps) {
- const [now, setNow] = useState(dayjs(0));
+ const [now, setNow] = useState(dayjs());
useInterval(() => {
setNow(dayjs());
@@ -52,7 +52,7 @@ function CountdownTimer(props: { date: Date } & TextProps) {
const { date, ...rest } = props;
- const kickoff = dayjs(props.date);
+ const kickoff = dayjs(date);
const diff = kickoff.diff(now, "second");
const days = Math.floor(diff / 86400);
const hours = Math.floor((diff % 86400) / 3600);
@@ -60,7 +60,7 @@ function CountdownTimer(props: { date: Date } & TextProps) {
const seconds = Math.floor(diff % 60);
return (
-
+
Kickoff in
{" "}
diff --git a/src/server/api/routers/worldChamps.router.ts b/src/server/api/routers/worldChamps.router.ts
index bd760a3..72e11cd 100644
--- a/src/server/api/routers/worldChamps.router.ts
+++ b/src/server/api/routers/worldChamps.router.ts
@@ -3,7 +3,7 @@ import { prisma } from "~/server/db";
import { requireNothing } from "~/utils/accessControl";
export const worldChampsRouter = createTRPCRouter({
- userStatus: publicProcedure.query(async ({ input, ctx }) => {
+ userStatus: publicProcedure.query(async ({ ctx }) => {
const userId = ctx.session?.user.id;
if (!userId) {
diff --git a/src/server/utils/deriveNewContructFn.ts b/src/server/utils/deriveNewContructFn.ts
index 32b7696..898a22d 100644
--- a/src/server/utils/deriveNewContructFn.ts
+++ b/src/server/utils/deriveNewContructFn.ts
@@ -3,7 +3,7 @@ import ivm from "isolated-vm";
import dedent from "dedent";
import { openai } from "./openai";
import { isObject } from "lodash-es";
-import { type CompletionCreateParams } from "openai/resources/chat/completions";
+import type { CreateChatCompletionRequestMessage } from "openai/resources/chat/completions";
import formatPromptConstructor from "~/utils/formatPromptConstructor";
import { type SupportedProvider, type Model } from "~/modelProviders/types";
import modelProviders from "~/modelProviders/modelProviders";
@@ -44,7 +44,7 @@ const requestUpdatedPromptFunction = async (
let newContructionFn = "";
for (let i = 0; i < NUM_RETRIES; i++) {
try {
- const messages: CompletionCreateParams.CreateChatCompletionRequestNonStreaming.Message[] = [
+ const messages: CreateChatCompletionRequestMessage[] = [
{
role: "system",
content: `Your job is to update prompt constructor functions. Here is the api shape for the current model:\n---\n${JSON.stringify(
diff --git a/src/theme/ChakraThemeProvider.tsx b/src/theme/ChakraThemeProvider.tsx
index 94d3a6c..0c3f247 100644
--- a/src/theme/ChakraThemeProvider.tsx
+++ b/src/theme/ChakraThemeProvider.tsx
@@ -1,10 +1,23 @@
import { extendTheme } from "@chakra-ui/react";
import "@fontsource/inconsolata";
import { ChakraProvider } from "@chakra-ui/react";
+import { modalAnatomy } from "@chakra-ui/anatomy";
+import { createMultiStyleConfigHelpers } from "@chakra-ui/styled-system";
const systemFont =
'ui-sans-serif, -apple-system, "system-ui", "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"';
+/* eslint-disable @typescript-eslint/unbound-method */
+const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(
+ modalAnatomy.keys,
+);
+
+const modalTheme = defineMultiStyleConfig({
+ baseStyle: definePartsStyle({
+ dialog: { borderRadius: "sm" },
+ }),
+});
+
const theme = extendTheme({
styles: {
global: (props: { colorMode: "dark" | "light" }) => ({
@@ -39,6 +52,7 @@ const theme = extendTheme({
},
},
},
+ Modal: modalTheme,
},
});