Compare commits

..

11 Commits

Author SHA1 Message Date
Kyle Corbitt
6be32bea4c Add debug modal for output cells
See the actual input that a model got for a specific cell. The formatting isn't great right now; should probably iterate on that.
2023-08-01 22:49:38 -07:00
arcticfly
026532f2c2 Model selection styling changes (#107)
* Model selection styling changes

* Fix prettier
2023-08-01 18:45:15 -07:00
Kyle Corbitt
f88538336f fix types 2023-08-01 18:31:34 -07:00
Kyle Corbitt
3c7178115e Merge pull request #105 from OpenPipe/bump-models
Bump Replicate models
2023-08-01 18:26:16 -07:00
Kyle Corbitt
292aaf090a Merge pull request #106 from OpenPipe/dark-mode
Update global background color in ChakraThemeProvider
2023-08-01 18:25:57 -07:00
Kyle Corbitt
d9915dc41b Update global background color in ChakraThemeProvider 2023-08-01 18:25:29 -07:00
David Corbitt
3560bcff14 Correct time stamps on waiting message 2023-08-01 18:09:23 -07:00
Kyle Corbitt
6982339a1a Bump Replicate models 2023-08-01 18:08:02 -07:00
arcticfly
d348b130d5 Add navbar to world-champs (#104)
* Add navbar to world-champs

* Move TopNavbar to signup.tsx
2023-08-01 16:59:46 -07:00
Kyle Corbitt
bf67580991 Merge pull request #103 from OpenPipe/world-champs
add created_at and updated_at to users
2023-08-01 16:49:11 -07:00
Kyle Corbitt
6184498810 Merge pull request #102 from OpenPipe/world-champs
world champs signup
2023-08-01 13:09:06 -07:00
20 changed files with 342 additions and 220 deletions

View File

@@ -25,8 +25,10 @@
"@apidevtools/json-schema-ref-parser": "^10.1.0", "@apidevtools/json-schema-ref-parser": "^10.1.0",
"@babel/preset-typescript": "^7.22.5", "@babel/preset-typescript": "^7.22.5",
"@babel/standalone": "^7.22.9", "@babel/standalone": "^7.22.9",
"@chakra-ui/anatomy": "^2.2.0",
"@chakra-ui/next-js": "^2.1.4", "@chakra-ui/next-js": "^2.1.4",
"@chakra-ui/react": "^2.7.1", "@chakra-ui/react": "^2.7.1",
"@chakra-ui/styled-system": "^2.9.1",
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@emotion/server": "^11.11.0", "@emotion/server": "^11.11.0",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
@@ -63,7 +65,7 @@
"next-auth": "^4.22.1", "next-auth": "^4.22.1",
"next-query-params": "^4.2.3", "next-query-params": "^4.2.3",
"nextjs-routes": "^2.0.1", "nextjs-routes": "^2.0.1",
"openai": "4.0.0-beta.2", "openai": "4.0.0-beta.7",
"pluralize": "^8.0.0", "pluralize": "^8.0.0",
"posthog-js": "^1.68.4", "posthog-js": "^1.68.4",
"prettier": "^3.0.0", "prettier": "^3.0.0",
@@ -72,6 +74,7 @@
"react-diff-viewer": "^3.1.1", "react-diff-viewer": "^3.1.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-icons": "^4.10.1", "react-icons": "^4.10.1",
"react-json-tree": "^0.18.0",
"react-select": "^5.7.4", "react-select": "^5.7.4",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",
"react-textarea-autosize": "^8.5.0", "react-textarea-autosize": "^8.5.0",

92
pnpm-lock.yaml generated
View File

@@ -17,12 +17,18 @@ dependencies:
'@babel/standalone': '@babel/standalone':
specifier: ^7.22.9 specifier: ^7.22.9
version: 7.22.9 version: 7.22.9
'@chakra-ui/anatomy':
specifier: ^2.2.0
version: 2.2.0
'@chakra-ui/next-js': '@chakra-ui/next-js':
specifier: ^2.1.4 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) 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': '@chakra-ui/react':
specifier: ^2.7.1 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) 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': '@emotion/react':
specifier: ^11.11.1 specifier: ^11.11.1
version: 11.11.1(@types/react@18.2.6)(react@18.2.0) version: 11.11.1(@types/react@18.2.6)(react@18.2.0)
@@ -132,8 +138,8 @@ dependencies:
specifier: ^2.0.1 specifier: ^2.0.1
version: 2.0.1(next@13.4.2) version: 2.0.1(next@13.4.2)
openai: openai:
specifier: 4.0.0-beta.2 specifier: 4.0.0-beta.7
version: 4.0.0-beta.2 version: 4.0.0-beta.7
pluralize: pluralize:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.0.0 version: 8.0.0
@@ -158,6 +164,9 @@ dependencies:
react-icons: react-icons:
specifier: ^4.10.1 specifier: ^4.10.1
version: 4.10.1(react@18.2.0) 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: react-select:
specifier: ^5.7.4 specifier: ^5.7.4
version: 5.7.4(@types/react@18.2.6)(react-dom@18.2.0)(react@18.2.0) 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==} resolution: {integrity: sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==}
dev: false 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): /@chakra-ui/avatar@2.2.11(@chakra-ui/system@2.5.8)(react@18.2.0):
resolution: {integrity: sha512-CJFkoWvlCTDJTUBrKA/aVyG5Zz6TBEIVmmsJtqC6VcQuVDTxkWod8ruXnjb0LT2DUveL7xR5qZM9a5IXcsH3zg==} resolution: {integrity: sha512-CJFkoWvlCTDJTUBrKA/aVyG5Zz6TBEIVmmsJtqC6VcQuVDTxkWod8ruXnjb0LT2DUveL7xR5qZM9a5IXcsH3zg==}
peerDependencies: peerDependencies:
@@ -2831,6 +2844,10 @@ packages:
'@babel/types': 7.22.5 '@babel/types': 7.22.5
dev: true dev: true
/@types/base16@1.0.2:
resolution: {integrity: sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==}
dev: false
/@types/body-parser@1.19.2: /@types/body-parser@1.19.2:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies: dependencies:
@@ -3013,6 +3030,7 @@ packages:
/@types/qs@6.9.7: /@types/qs@6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
dev: true
/@types/range-parser@1.2.4: /@types/range-parser@1.2.4:
resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
@@ -3658,6 +3676,10 @@ packages:
resolution: {integrity: sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==} resolution: {integrity: sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==}
dev: false dev: false
/base16@1.0.0:
resolution: {integrity: sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==}
dev: false
/base64-js@0.0.8: /base64-js@0.0.8:
resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@@ -3916,10 +3938,24 @@ packages:
/color-name@1.1.4: /color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 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: /color2k@2.0.2:
resolution: {integrity: sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==} resolution: {integrity: sha512-kJhwH5nAwb34tmyuqq/lgjEKzlFXn1U99NlnB6Ws4qVaERcRUYeYP1cBw6BJ4vxaWStAUEef4WMr7WjOCnBt8w==}
dev: false 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: /combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@@ -5536,6 +5572,10 @@ packages:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: false dev: false
/is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
dev: false
/is-bigint@1.0.4: /is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
dependencies: dependencies:
@@ -5910,6 +5950,10 @@ packages:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: false dev: false
/lodash.curry@4.1.1:
resolution: {integrity: sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==}
dev: false
/lodash.merge@4.6.2: /lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true dev: true
@@ -6387,19 +6431,17 @@ packages:
is-wsl: 2.2.0 is-wsl: 2.2.0
dev: true dev: true
/openai@4.0.0-beta.2: /openai@4.0.0-beta.7:
resolution: {integrity: sha512-zTuAxBFe5nSO7LngbV+/O0udtgHWfXb2lFei8/sDY4GB5cOdnrRoSOtiyUfV65ANdvlI4F75oYZX7w067cxj3w==} resolution: {integrity: sha512-jHjwvpMuGkNxiQ3erwLZsOvPEhcVrMtwtfNeYmGCjhbdB+oStVw/7pIhIPkualu8rlhLwgMR7awknIaN3IQcOA==}
dependencies: dependencies:
'@types/node': 18.16.0 '@types/node': 18.16.0
'@types/node-fetch': 2.6.4 '@types/node-fetch': 2.6.4
'@types/qs': 6.9.7
abort-controller: 3.0.0 abort-controller: 3.0.0
agentkeepalive: 4.3.0 agentkeepalive: 4.3.0
digest-fetch: 1.3.0 digest-fetch: 1.3.0
form-data-encoder: 1.7.2 form-data-encoder: 1.7.2
formdata-node: 4.4.1 formdata-node: 4.4.1
node-fetch: 2.6.12 node-fetch: 2.6.12
qs: 6.11.2
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
- supports-color - supports-color
@@ -6832,13 +6874,6 @@ packages:
side-channel: 1.0.4 side-channel: 1.0.4
dev: false 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: /queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true dev: true
@@ -6875,6 +6910,18 @@ packages:
webpack: 5.88.2 webpack: 5.88.2
dev: true 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): /react-clientside-effect@1.2.6(react@18.2.0):
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==} resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
peerDependencies: peerDependencies:
@@ -6949,6 +6996,19 @@ packages:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: true 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): /react-remove-scroll-bar@2.3.4(@types/react@18.2.6)(react@18.2.0):
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
engines: {node: '>=10'} engines: {node: '>=10'}
@@ -7360,6 +7420,12 @@ packages:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true 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: /slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'} engines: {node: '>=8'}

View File

@@ -22,8 +22,8 @@ export const ModelSearch = (props: {
const [containerRef, containerDimensions] = useElementDimensions(); const [containerRef, containerDimensions] = useElementDimensions();
return ( return (
<VStack ref={containerRef as LegacyRef<HTMLDivElement>} w="full"> <VStack ref={containerRef as LegacyRef<HTMLDivElement>} w="full" fontFamily="inconsolata">
<Text>Browse Models</Text> <Text fontWeight="bold">Browse Models</Text>
<Select<ProviderModel> <Select<ProviderModel>
styles={{ control: (provided) => ({ ...provided, width: containerDimensions?.width }) }} styles={{ control: (provided) => ({ ...provided, width: containerDimensions?.width }) }}
getOptionLabel={(data) => modelLabel(data.provider, data.model)} getOptionLabel={(data) => modelLabel(data.provider, data.model)}

View File

@@ -23,16 +23,24 @@ export const ModelStatsCard = ({
{label} {label}
</Text> </Text>
<VStack w="full" spacing={6} bgColor="gray.100" p={4} borderRadius={4}> <VStack
w="full"
spacing={6}
borderWidth={1}
borderColor="gray.300"
p={4}
borderRadius={8}
fontFamily="inconsolata"
>
<HStack w="full" align="flex-start"> <HStack w="full" align="flex-start">
<Text flex={1} fontSize="lg"> <VStack flex={1} fontSize="lg" alignItems="flex-start">
<Text as="span" color="gray.600">
{model.provider} /{" "}
</Text>
<Text as="span" fontWeight="bold" color="gray.900"> <Text as="span" fontWeight="bold" color="gray.900">
{model.name} {model.name}
</Text> </Text>
</Text> <Text as="span" color="gray.600" fontSize="sm">
Provider: {model.provider}
</Text>
</VStack>
<Link <Link
href={model.learnMoreUrl} href={model.learnMoreUrl}
isExternal isExternal

View File

@@ -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) => (
<VStack w="full" alignItems="flex-start" {...props}>
<CellOptions refetchingOutput={hardRefetching} refetchOutput={hardRefetch} />
<VStack w="full" alignItems="flex-start" maxH={500} overflowY="auto">
{children}
</VStack>
</VStack>
);

View File

@@ -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 (
<HStack justifyContent="flex-end" w="full">
{canModify && (
<Tooltip label="Refetch output" aria-label="refetch output">
<Button
size="xs"
w={4}
h={4}
py={4}
px={4}
minW={0}
borderRadius={8}
color="gray.500"
variant="ghost"
cursor="pointer"
onClick={refetchOutput}
aria-label="refetch output"
>
<Icon as={refetchingOutput ? Spinner : BsArrowClockwise} boxSize={4} />
</Button>
</Tooltip>
)}
</HStack>
);
};

View File

@@ -1,17 +1,17 @@
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { type PromptVariant, type Scenario } from "../types"; 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 { useExperiment, useHandledAsyncCallback } from "~/utils/hooks";
import SyntaxHighlighter from "react-syntax-highlighter"; import SyntaxHighlighter from "react-syntax-highlighter";
import { docco } from "react-syntax-highlighter/dist/cjs/styles/hljs"; import { docco } from "react-syntax-highlighter/dist/cjs/styles/hljs";
import stringify from "json-stringify-pretty-compact"; 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 useSocket from "~/utils/useSocket";
import { OutputStats } from "./OutputStats"; import { OutputStats } from "./OutputStats";
import { RetryCountdown } from "./RetryCountdown"; import { RetryCountdown } from "./RetryCountdown";
import frontendModelProviders from "~/modelProviders/frontendModelProviders"; import frontendModelProviders from "~/modelProviders/frontendModelProviders";
import { ResponseLog } from "./ResponseLog"; import { ResponseLog } from "./ResponseLog";
import { CellContent } from "./CellContent"; import { CellOptions } from "./TopActions";
const WAITING_MESSAGE_INTERVAL = 20000; const WAITING_MESSAGE_INTERVAL = 20000;
@@ -72,37 +72,49 @@ export default function OutputCell({
// TODO: disconnect from socket if we're not streaming anymore // TODO: disconnect from socket if we're not streaming anymore
const streamedMessage = useSocket<OutputSchema>(cell?.id); const streamedMessage = useSocket<OutputSchema>(cell?.id);
const mostRecentResponse = cell?.modelResponses[cell.modelResponses.length - 1];
const CellWrapper = useCallback(
({ children, ...props }: StackProps) => (
<VStack w="full" alignItems="flex-start" {...props} px={2} py={2} h="100%">
{cell && (
<CellOptions refetchingOutput={hardRefetching} refetchOutput={hardRefetch} cell={cell} />
)}
<VStack w="full" alignItems="flex-start" maxH={500} overflowY="auto" flex={1}>
{children}
</VStack>
{mostRecentResponse && (
<OutputStats modelResponse={mostRecentResponse} scenario={scenario} />
)}
</VStack>
),
[hardRefetching, hardRefetch, mostRecentResponse, scenario],
);
if (!vars) return null; if (!vars) return null;
if (!cell && !fetchingOutput) if (!cell && !fetchingOutput)
return ( return (
<CellContent hardRefetching={hardRefetching} hardRefetch={hardRefetch}> <CellWrapper>
<Text color="gray.500">Error retrieving output</Text> <Text color="gray.500">Error retrieving output</Text>
</CellContent> </CellWrapper>
); );
if (cell && cell.errorMessage) { if (cell && cell.errorMessage) {
return ( return (
<CellContent hardRefetching={hardRefetching} hardRefetch={hardRefetch}> <CellWrapper>
<Text color="red.500">{cell.errorMessage}</Text> <Text color="red.500">{cell.errorMessage}</Text>
</CellContent> </CellWrapper>
); );
} }
if (disabledReason) return <Text color="gray.500">{disabledReason}</Text>; if (disabledReason) return <Text color="gray.500">{disabledReason}</Text>;
const mostRecentResponse = cell?.modelResponses[cell.modelResponses.length - 1];
const showLogs = !streamedMessage && !mostRecentResponse?.output; const showLogs = !streamedMessage && !mostRecentResponse?.output;
if (showLogs) if (showLogs)
return ( return (
<CellContent <CellWrapper alignItems="flex-start" fontFamily="inconsolata, monospace" spacing={0}>
hardRefetching={hardRefetching}
hardRefetch={hardRefetch}
alignItems="flex-start"
fontFamily="inconsolata, monospace"
spacing={0}
>
{cell?.jobQueuedAt && <ResponseLog time={cell.jobQueuedAt} title="Job queued" />} {cell?.jobQueuedAt && <ResponseLog time={cell.jobQueuedAt} title="Job queued" />}
{cell?.jobStartedAt && <ResponseLog time={cell.jobStartedAt} title="Job started" />} {cell?.jobStartedAt && <ResponseLog time={cell.jobStartedAt} title="Job started" />}
{cell?.modelResponses?.map((response) => { {cell?.modelResponses?.map((response) => {
@@ -124,9 +136,13 @@ export default function OutputCell({
Array.from({ length: numWaitingMessages }, (_, i) => ( Array.from({ length: numWaitingMessages }, (_, i) => (
<ResponseLog <ResponseLog
key={`waiting-${i}`} key={`waiting-${i}`}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion time={
time={new Date(response.requestedAt!.getTime() + i * WAITING_MESSAGE_INTERVAL)} new Date(
title="Waiting for response" (response.requestedAt?.getTime?.() ?? 0) +
(i + 1) * WAITING_MESSAGE_INTERVAL,
)
}
title="Waiting for response..."
/> />
))} ))}
{response.receivedAt && ( {response.receivedAt && (
@@ -144,7 +160,7 @@ export default function OutputCell({
{mostRecentResponse?.retryTime && ( {mostRecentResponse?.retryTime && (
<RetryCountdown retryTime={mostRecentResponse.retryTime} /> <RetryCountdown retryTime={mostRecentResponse.retryTime} />
)} )}
</CellContent> </CellWrapper>
); );
const normalizedOutput = mostRecentResponse?.output const normalizedOutput = mostRecentResponse?.output
@@ -155,50 +171,27 @@ export default function OutputCell({
if (mostRecentResponse?.output && normalizedOutput?.type === "json") { if (mostRecentResponse?.output && normalizedOutput?.type === "json") {
return ( return (
<VStack <CellWrapper>
w="100%" <SyntaxHighlighter
h="100%" customStyle={{ overflowX: "unset", width: "100%", flex: 1 }}
fontSize="xs" language="json"
flexWrap="wrap" style={docco}
overflowX="hidden" lineProps={{
justifyContent="space-between" style: { wordBreak: "break-all", whiteSpace: "pre-wrap" },
> }}
<CellContent wrapLines
hardRefetching={hardRefetching}
hardRefetch={hardRefetch}
w="full"
flex={1}
spacing={0}
> >
<SyntaxHighlighter {stringify(normalizedOutput.value, { maxLength: 40 })}
customStyle={{ overflowX: "unset", width: "100%", flex: 1 }} </SyntaxHighlighter>
language="json" </CellWrapper>
style={docco}
lineProps={{
style: { wordBreak: "break-all", whiteSpace: "pre-wrap" },
}}
wrapLines
>
{stringify(normalizedOutput.value, { maxLength: 40 })}
</SyntaxHighlighter>
</CellContent>
<OutputStats modelResponse={mostRecentResponse} scenario={scenario} />
</VStack>
); );
} }
const contentToDisplay = (normalizedOutput?.type === "text" && normalizedOutput.value) || ""; const contentToDisplay = (normalizedOutput?.type === "text" && normalizedOutput.value) || "";
return ( return (
<VStack w="100%" h="100%" justifyContent="space-between" whiteSpace="pre-wrap"> <CellWrapper>
<VStack w="full" alignItems="flex-start" spacing={0}> <Text>{contentToDisplay}</Text>
<CellContent hardRefetching={hardRefetching} hardRefetch={hardRefetch}> </CellWrapper>
<Text>{contentToDisplay}</Text>
</CellContent>
</VStack>
{mostRecentResponse?.output && (
<OutputStats modelResponse={mostRecentResponse} scenario={scenario} />
)}
</VStack>
); );
} }

View File

@@ -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<RouterOutputs["scenarioVariantCells"]["get"]>;
disclosure: UseDisclosureReturn;
}) {
return (
<Modal isOpen={props.disclosure.isOpen} onClose={props.disclosure.onClose} size="2xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>Prompt</ModalHeader>
<ModalCloseButton />
<ModalBody>
<JSONTree
data={props.cell.prompt}
invertTheme={true}
theme="chalk"
shouldExpandNodeInitially={() => true}
getItemString={() => ""}
hideRoot
/>
</ModalBody>
</ModalContent>
</Modal>
);
}

View File

@@ -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 (
<HStack justifyContent="flex-end" w="full">
{cell && (
<>
<Tooltip label="See Prompt">
<IconButton
aria-label="See Prompt"
icon={<Icon as={BsInfoCircle} boxSize={4} />}
onClick={modalDisclosure.onOpen}
size="xs"
colorScheme="gray"
color="gray.500"
variant="ghost"
/>
</Tooltip>
<ExpandedModal cell={cell} disclosure={modalDisclosure} />
</>
)}
{canModify && (
<Tooltip label="Refetch output">
<IconButton
size="xs"
color="gray.500"
variant="ghost"
cursor="pointer"
onClick={refetchOutput}
aria-label="refetch output"
icon={<Icon as={refetchingOutput ? Spinner : BsArrowClockwise} boxSize={4} />}
/>
</Tooltip>
)}
</HStack>
);
};

View File

@@ -1,9 +1,8 @@
import { useEffect, type DragEvent } from "react";
import { api } from "~/utils/api";
import { isEqual } from "lodash-es"; 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 { useExperiment, useExperimentAccess, useHandledAsyncCallback } from "~/utils/hooks";
import { useState } from "react"; import { type Scenario } from "./types";
import { import {
Box, Box,
@@ -12,14 +11,12 @@ import {
Icon, Icon,
IconButton, IconButton,
Spinner, Spinner,
Stack, Text,
Tooltip, Tooltip,
VStack, VStack,
Text,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { cellPadding } from "../constants";
import { BsArrowsAngleExpand, BsX } from "react-icons/bs"; import { BsArrowsAngleExpand, BsX } from "react-icons/bs";
import { RiDraggable } from "react-icons/ri"; import { cellPadding } from "../constants";
import { FloatingLabelInput } from "./FloatingLabelInput"; import { FloatingLabelInput } from "./FloatingLabelInput";
import { ScenarioEditorModal } from "./ScenarioEditorModal"; import { ScenarioEditorModal } from "./ScenarioEditorModal";
@@ -115,60 +112,44 @@ export default function ScenarioEditor({
onDrop={onReorder} onDrop={onReorder}
backgroundColor={isDragTarget ? "gray.100" : "transparent"} backgroundColor={isDragTarget ? "gray.100" : "transparent"}
> >
{canModify && props.canHide && (
<Stack
alignSelf="flex-start"
opacity={props.hovered ? 1 : 0}
spacing={0}
ml={-cellPadding.x}
>
<Tooltip label="Hide scenario" hasArrow>
{/* for some reason the tooltip can't position itself properly relative to the icon without the wrapping box */}
<Button
variant="unstyled"
color="gray.400"
height="unset"
width="unset"
minW="unset"
onClick={onHide}
_hover={{
color: "gray.800",
cursor: "pointer",
}}
>
<Icon as={hidingInProgress ? Spinner : BsX} boxSize={hidingInProgress ? 4 : 6} />
</Button>
</Tooltip>
<Icon
as={RiDraggable}
boxSize={6}
color="gray.400"
_hover={{ color: "gray.800", cursor: "pointer" }}
/>
</Stack>
)}
{variableLabels.length === 0 ? ( {variableLabels.length === 0 ? (
<Box color="gray.500"> <Box color="gray.500">
{vars.data ? "No scenario variables configured" : "Loading..."} {vars.data ? "No scenario variables configured" : "Loading..."}
</Box> </Box>
) : ( ) : (
<VStack spacing={4} flex={1} py={2}> <VStack spacing={4} flex={1} py={2}>
<HStack justifyContent="space-between" w="100%"> <HStack justifyContent="space-between" w="100%" align="center" spacing={0}>
<Text color="gray.500">Scenario</Text> <Text flex={1}>Scenario</Text>
<IconButton <Tooltip label="Expand" hasArrow>
className="fullscreen-toggle" <IconButton
aria-label="Maximize" aria-label="Expand"
icon={<BsArrowsAngleExpand />} icon={<Icon as={BsArrowsAngleExpand} boxSize={3} />}
onClick={() => setScenarioEditorModalOpen(true)} onClick={() => setScenarioEditorModalOpen(true)}
boxSize={6} size="xs"
borderRadius={4} colorScheme="gray"
p={1.5} color="gray.500"
minW={0} variant="ghost"
colorScheme="gray" />
color="gray.500" </Tooltip>
variant="ghost" {canModify && props.canHide && (
/> <Tooltip label="Delete" hasArrow>
<IconButton
aria-label="Delete"
icon={
<Icon
as={hidingInProgress ? Spinner : BsX}
boxSize={hidingInProgress ? 4 : 6}
/>
}
onClick={onHide}
size="xs"
display="flex"
colorScheme="gray"
color="gray.500"
variant="ghost"
/>
</Tooltip>
)}
</HStack> </HStack>
{variableLabels.map((key) => { {variableLabels.map((key) => {
const value = values[key] ?? ""; const value = values[key] ?? "";

View File

@@ -1,7 +1,6 @@
import { import {
Button, Button,
HStack, HStack,
Icon,
Modal, Modal,
ModalBody, ModalBody,
ModalCloseButton, ModalCloseButton,
@@ -14,7 +13,6 @@ import {
VStack, VStack,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { BsFileTextFill } from "react-icons/bs";
import { isEqual } from "lodash-es"; import { isEqual } from "lodash-es";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
@@ -60,8 +58,6 @@ export const ScenarioEditorModal = ({
await utils.scenarios.list.invalidate(); await utils.scenarios.list.invalidate();
}, [mutation, values]); }, [mutation, values]);
console.log("scenario", scenario);
const vars = api.templateVars.list.useQuery({ experimentId: experiment.data?.id ?? "" }); const vars = api.templateVars.list.useQuery({ experimentId: experiment.data?.id ?? "" });
const variableLabels = vars.data?.map((v) => v.label) ?? []; const variableLabels = vars.data?.map((v) => v.label) ?? [];
@@ -73,12 +69,7 @@ export const ScenarioEditorModal = ({
> >
<ModalOverlay /> <ModalOverlay />
<ModalContent w={1200}> <ModalContent w={1200}>
<ModalHeader> <ModalHeader />
<HStack>
<Icon as={BsFileTextFill} />
<Text>Scenario</Text>
</HStack>
</ModalHeader>
<ModalCloseButton /> <ModalCloseButton />
<ModalBody maxW="unset"> <ModalBody maxW="unset">
<VStack spacing={8}> <VStack spacing={8}>

View File

@@ -1,6 +1,5 @@
import { Box, GridItem } from "@chakra-ui/react"; import { GridItem } from "@chakra-ui/react";
import React, { useState } from "react"; import React, { useState } from "react";
import { cellPadding } from "../constants";
import OutputCell from "./OutputCell/OutputCell"; import OutputCell from "./OutputCell/OutputCell";
import ScenarioEditor from "./ScenarioEditor"; import ScenarioEditor from "./ScenarioEditor";
import type { PromptVariant, Scenario } from "./types"; import type { PromptVariant, Scenario } from "./types";
@@ -39,9 +38,7 @@ const ScenarioRow = (props: {
colStart={i + 2} colStart={i + 2}
{...borders} {...borders}
> >
<Box h="100%" w="100%" px={cellPadding.x} py={cellPadding.y}> <OutputCell key={variant.id} scenario={props.scenario} variant={variant} />
<OutputCell key={variant.id} scenario={props.scenario} variant={variant} />
</Box>
</GridItem> </GridItem>
))} ))}
</> </>

View File

@@ -6,7 +6,7 @@ import {
} from "openai/resources/chat"; } from "openai/resources/chat";
import { countOpenAIChatTokens } from "~/utils/countTokens"; import { countOpenAIChatTokens } from "~/utils/countTokens";
import { type CompletionResponse } from "../types"; import { type CompletionResponse } from "../types";
import { omit } from "lodash-es"; import { isArray, isString, omit } from "lodash-es";
import { openai } from "~/server/utils/openai"; import { openai } from "~/server/utils/openai";
import { truthyFilter } from "~/utils/utils"; import { truthyFilter } from "~/utils/utils";
import { APIError } from "openai"; import { APIError } from "openai";
@@ -40,6 +40,8 @@ const mergeStreamedChunks = (
((choice.delta.function_call.arguments as string) ?? ""); ((choice.delta.function_call.arguments as string) ?? "");
} }
} else { } 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 } }); choices.push({ ...omit(choice, "delta"), message: { role: "assistant", ...choice.delta } });
} }
} }
@@ -64,6 +66,7 @@ export async function getCompletion(
try { try {
if (onStream) { if (onStream) {
console.log("got started");
const resp = await openai.chat.completions.create( const resp = await openai.chat.completions.create(
{ ...input, stream: true }, { ...input, stream: true },
{ {
@@ -71,9 +74,11 @@ export async function getCompletion(
}, },
); );
for await (const part of resp) { for await (const part of resp) {
console.log("got part", part);
finalCompletion = mergeStreamedChunks(finalCompletion, part); finalCompletion = mergeStreamedChunks(finalCompletion, part);
onStream(finalCompletion); onStream(finalCompletion);
} }
console.log("got final", finalCompletion);
if (!finalCompletion) { if (!finalCompletion) {
return { return {
type: "error", type: "error",
@@ -121,9 +126,17 @@ export async function getCompletion(
}; };
} catch (error: unknown) { } catch (error: unknown) {
if (error instanceof APIError) { 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 { return {
type: "error", type: "error",
message: error.message, message,
autoRetry: error.status === 429 || error.status === 503, autoRetry: error.status === 429 || error.status === 503,
statusCode: error.status, statusCode: error.status,
}; };

View File

@@ -8,8 +8,8 @@ const replicate = new Replicate({
}); });
const modelIds: Record<ReplicateLlama2Input["model"], string> = { const modelIds: Record<ReplicateLlama2Input["model"], string> = {
"7b-chat": "5ec5fdadd80ace49f5a2b2178cceeb9f2f77c493b85b1131002c26e6b2b13184", "7b-chat": "058333670f2a6e88cf1b29b8183405b17bb997767282f790b82137df8c090c1f",
"13b-chat": "6b4da803a2382c08868c5af10a523892f38e2de1aafb2ee55b020d9efef2fdb8", "13b-chat": "d5da4236b006f967ceb7da037be9cfc3924b20d21fed88e1e94f19d56e2d3111",
"70b-chat": "2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1", "70b-chat": "2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1",
}; };

View File

@@ -54,7 +54,7 @@ const modelProvider: ReplicateLlama2Provider = {
temperature: { temperature: {
type: "number", type: "number",
description: description:
"Adjusts randomness of outputs, greater than 1 is random and 0 is deterministic, 0.75 is a good starting value. (minimum: 0.01; maximum: 5)", "Adjusts randomness of outputs, 0.1 is a good starting value. (minimum: 0.01; maximum: 5)",
}, },
top_p: { top_p: {
type: "number", type: "number",

View File

@@ -9,7 +9,7 @@ const inconsolataRegularFontP = fetch(
new URL("../../../../public/fonts/Inconsolata_SemiExpanded-Medium.ttf", import.meta.url), new URL("../../../../public/fonts/Inconsolata_SemiExpanded-Medium.ttf", import.meta.url),
).then((res) => res.arrayBuffer()); ).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 // @ts-expect-error - nextUrl is not defined on NextApiRequest for some reason
const searchParams = req.nextUrl?.searchParams as URLSearchParams; const searchParams = req.nextUrl?.searchParams as URLSearchParams;
const experimentLabel = searchParams.get("experimentLabel"); const experimentLabel = searchParams.get("experimentLabel");

View File

@@ -17,6 +17,7 @@ import {
Tr, Tr,
VStack, VStack,
useInterval, useInterval,
Image,
} from "@chakra-ui/react"; } from "@chakra-ui/react";
import { signIn, useSession } from "next-auth/react"; import { signIn, useSession } from "next-auth/react";
import Head from "next/head"; import Head from "next/head";
@@ -27,9 +28,23 @@ import { api } from "~/utils/api";
import dayjs from "~/utils/dayjs"; import dayjs from "~/utils/dayjs";
import { useHandledAsyncCallback } from "~/utils/hooks"; import { useHandledAsyncCallback } from "~/utils/hooks";
const TopNavbar = () => (
<DarkMode>
<GlobalStyle />
<HStack px={4} py={2}>
<HStack as={Link} href="/" _hover={{ textDecoration: "none" }} spacing={0} py={2} pr={16}>
<Image src="/logo.svg" alt="" boxSize={6} mr={4} />
<Heading size="md" fontFamily="inconsolata, monospace">
OpenPipe
</Heading>
</HStack>
</HStack>
</DarkMode>
);
// Shows how long until the competition starts. Refreshes every second // Shows how long until the competition starts. Refreshes every second
function CountdownTimer(props: { date: Date } & TextProps) { function CountdownTimer(props: { date: Date } & TextProps) {
const [now, setNow] = useState(dayjs(0)); const [now, setNow] = useState(dayjs());
useInterval(() => { useInterval(() => {
setNow(dayjs()); setNow(dayjs());
@@ -37,7 +52,7 @@ function CountdownTimer(props: { date: Date } & TextProps) {
const { date, ...rest } = props; const { date, ...rest } = props;
const kickoff = dayjs(props.date); const kickoff = dayjs(date);
const diff = kickoff.diff(now, "second"); const diff = kickoff.diff(now, "second");
const days = Math.floor(diff / 86400); const days = Math.floor(diff / 86400);
const hours = Math.floor((diff % 86400) / 3600); const hours = Math.floor((diff % 86400) / 3600);
@@ -45,7 +60,7 @@ function CountdownTimer(props: { date: Date } & TextProps) {
const seconds = Math.floor(diff % 60); const seconds = Math.floor(diff % 60);
return ( return (
<Text {...rest}> <Text {...rest} suppressHydrationWarning>
<Text as="span" fontWeight="bold"> <Text as="span" fontWeight="bold">
Kickoff in Kickoff in
</Text>{" "} </Text>{" "}
@@ -128,7 +143,8 @@ export default function Signup() {
/> />
</Head> </Head>
<Box bgColor="gray.900" color="gray.200" minH="100vh" w="full"> <Box color="gray.200" minH="100vh" w="full">
<TopNavbar />
<VStack mx="auto" py={24} maxW="2xl" align="start" fontSize="lg"> <VStack mx="auto" py={24} maxW="2xl" align="start" fontSize="lg">
<Heading size="lg">🏆 Prompt Engineering World Championships</Heading> <Heading size="lg">🏆 Prompt Engineering World Championships</Heading>
<CountdownTimer <CountdownTimer

View File

@@ -3,7 +3,7 @@ import { prisma } from "~/server/db";
import { requireNothing } from "~/utils/accessControl"; import { requireNothing } from "~/utils/accessControl";
export const worldChampsRouter = createTRPCRouter({ export const worldChampsRouter = createTRPCRouter({
userStatus: publicProcedure.query(async ({ input, ctx }) => { userStatus: publicProcedure.query(async ({ ctx }) => {
const userId = ctx.session?.user.id; const userId = ctx.session?.user.id;
if (!userId) { if (!userId) {

View File

@@ -3,7 +3,7 @@ import ivm from "isolated-vm";
import dedent from "dedent"; import dedent from "dedent";
import { openai } from "./openai"; import { openai } from "./openai";
import { isObject } from "lodash-es"; 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 formatPromptConstructor from "~/utils/formatPromptConstructor";
import { type SupportedProvider, type Model } from "~/modelProviders/types"; import { type SupportedProvider, type Model } from "~/modelProviders/types";
import modelProviders from "~/modelProviders/modelProviders"; import modelProviders from "~/modelProviders/modelProviders";
@@ -44,14 +44,14 @@ const requestUpdatedPromptFunction = async (
let newContructionFn = ""; let newContructionFn = "";
for (let i = 0; i < NUM_RETRIES; i++) { for (let i = 0; i < NUM_RETRIES; i++) {
try { try {
const messages: CompletionCreateParams.CreateChatCompletionRequestNonStreaming.Message[] = [ const messages: CreateChatCompletionRequestMessage[] = [
{ {
role: "system", role: "system",
content: `Your job is to update prompt constructor functions. Here is the api shape for the current model:\n---\n${JSON.stringify( content: `Your job is to update prompt constructor functions. Here is the api shape for the current model:\n---\n${JSON.stringify(
originalModelProvider.inputSchema, originalModelProvider.inputSchema,
null, null,
2, 2,
)}\n\nDo not add any assistant messages.`, )}\n\nDo not add any assistant messages. Do not add any extra fields to the schema. Try to keep temperature consistent.`,
}, },
{ {
role: "user", role: "user",

View File

@@ -1,11 +1,31 @@
import { extendTheme } from "@chakra-ui/react"; import { extendTheme } from "@chakra-ui/react";
import "@fontsource/inconsolata"; import "@fontsource/inconsolata";
import { ChakraProvider } from "@chakra-ui/react"; import { ChakraProvider } from "@chakra-ui/react";
import { modalAnatomy } from "@chakra-ui/anatomy";
import { createMultiStyleConfigHelpers } from "@chakra-ui/styled-system";
const systemFont = const systemFont =
'ui-sans-serif, -apple-system, "system-ui", "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"'; '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({ const theme = extendTheme({
styles: {
global: (props: { colorMode: "dark" | "light" }) => ({
"html, body": {
backgroundColor: props.colorMode === "dark" ? "gray.900" : "white",
},
}),
},
fonts: { fonts: {
heading: systemFont, heading: systemFont,
body: systemFont, body: systemFont,
@@ -32,6 +52,7 @@ const theme = extendTheme({
}, },
}, },
}, },
Modal: modalTheme,
}, },
}); });