Skip to content

Commit

Permalink
Merge pull request #151 from yello-xyz/v0.24
Browse files Browse the repository at this point in the history
V0.24
  • Loading branch information
hverlind committed Feb 6, 2024
2 parents fd20a81 + 57764b9 commit 2b0ffc3
Show file tree
Hide file tree
Showing 107 changed files with 2,281 additions and 1,042 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## PlayFetch Changelog

### v0.24 - 2024-02-06
- Linear integration
- Support for Meta Llama 2 through Hugging Face

### v0.23 - 2024-01-23
- Reusable test data
- Cancel long running LLM requests
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ In order to run the app locally, you will need to add some additional variables

`GITHUB_APP_PRIVATE_KEY=` *[Generate a new private key at https://github.com/organizations/yello-xyz/settings/apps/play-fetch-local]*

- **To use Linear integration:**

`LINEAR_APP_CLIENT_ID=` *[Copy this from https://linear.app/playfetch-dev/settings/api]*

`LINEAR_APP_CLIENT_SECRET=` *[Copy this from https://linear.app/playfetch-dev/settings/api]*

`LINEAR_APP_WEBHOOK_SECRET=` *[Copy this from https://linear.app/playfetch-dev/settings/api]*

- **To use Email authentication:**

`[email protected]`
Expand Down
2 changes: 1 addition & 1 deletion __tests__/extractVariables.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ExtractCodeInterrupts, ExtractPromptVariables, ExtractVariables } from '@/src/common/formatting'
import { ChainItemWithInputs, Prompts } from '@/types'
import { DefaultPromptConfig } from '@/src/common/defaultConfig'
import { DefaultPromptConfig } from '@/src/common/defaults'
import { ExtractUnboundChainInputs } from '@/components/chains/chainItems'

const testExtractVariables = (testDescription: string, expectedVariables: string[], content: string) =>
Expand Down
2 changes: 1 addition & 1 deletion __tests__/serialize.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultPromptConfig, DefaultPrompts } from '@/src/common/defaultConfig'
import { DefaultPromptConfig, DefaultPrompts } from '@/src/common/defaults'
import { deserializePromptVersion, serializePromptVersion } from '@/src/server/serialize'
import { PromptConfig, Prompts } from '@/types'

Expand Down
2 changes: 1 addition & 1 deletion __tests__/versionsEqual.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultPromptConfig } from '@/src/common/defaultConfig'
import { DefaultPromptConfig } from '@/src/common/defaults'
import { ChainVersionsAreEqual, PromptVersionsAreEqual } from '@/src/common/versionsEqual'
import { LanguageModel, PromptConfig, Prompts } from '@/types'

Expand Down
3 changes: 3 additions & 0 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ steps:
- 'GITHUB_APP_CLIENT_ID=${_GITHUB_APP_CLIENT_ID}'
- 'GITHUB_APP_CLIENT_SECRET=${_GITHUB_APP_CLIENT_SECRET}'
- 'GITHUB_APP_PRIVATE_KEY=${_GITHUB_APP_PRIVATE_KEY}'
- 'LINEAR_APP_CLIENT_ID=${_LINEAR_APP_CLIENT_ID}'
- 'LINEAR_APP_CLIENT_SECRET=${_LINEAR_APP_CLIENT_SECRET}'
- 'LINEAR_APP_WEBHOOK_SECRET=${_LINEAR_APP_WEBHOOK_SECRET}'
- 'NEXTAUTH_SECRET=${_NEXTAUTH_SECRET}'
- 'NEXTAUTH_URL=${_NEXTAUTH_URL}'
- 'NOREPLY_EMAIL_PASSWORD=${_NOREPLY_EMAIL_PASSWORD}'
Expand Down
84 changes: 84 additions & 0 deletions components/admin/mainAdminPane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { ActiveUser, ProjectMetrics, RecentProject, User, UserMetrics, WorkspaceMetrics } from '@/types'
import Waitlist from '@/components/admin/waitlist'
import { useRouter } from 'next/router'
import ActiveUsers from '@/components/admin/activeUsers'
import RecentProjects from '@/components/admin/recentProjects'
import {
ActiveUsersItem,
AdminItem,
AdminItemIsProject,
AdminItemIsUser,
RecentProjectsItem,
WaitlistItem,
} from '@/src/common/admin/adminItem'
import ActiveUserMetrics from '@/components/admin/activeUserMetrics'
import RecentProjectMetrics from './recentProjectMetrics'
import RecentWorkspaceMetrics from './workspaceMetrics'

export default function MainAdminPane({
adminItem,
userMetrics,
projectMetrics,
workspaceMetrics,
activeUsers,
recentProjects,
waitlistUsers,
selectItem,
fetchActiveUsersBefore,
}: {
adminItem: AdminItem
userMetrics: UserMetrics | null
projectMetrics: ProjectMetrics | null
workspaceMetrics: WorkspaceMetrics | null
activeUsers: ActiveUser[]
waitlistUsers: User[]
recentProjects: RecentProject[]
selectItem: (
item: typeof WaitlistItem | typeof ActiveUsersItem | typeof RecentProjectsItem | number,
isWorkspace?: boolean
) => void
fetchActiveUsersBefore: () => Promise<void>
}) {
const router = useRouter()

return (
<div className='flex flex-col flex-1 bg-gray-25'>
{adminItem === WaitlistItem && <Waitlist initialWaitlistUsers={waitlistUsers} />}
{adminItem === ActiveUsersItem && (
<ActiveUsers activeUsers={activeUsers} onFetchBefore={fetchActiveUsersBefore} onSelectUser={selectItem} />
)}
{adminItem === RecentProjectsItem && (
<RecentProjects
recentProjects={recentProjects}
onSelectProject={selectItem}
onSelectWorkspace={workspaceID => selectItem(workspaceID, true)}
/>
)}
{userMetrics && AdminItemIsUser(adminItem) && (
<ActiveUserMetrics
user={adminItem}
metrics={userMetrics}
onDismiss={() => router.back()}
onSelectProject={selectItem}
onSelectWorkspace={workspaceID => selectItem(workspaceID, true)}
/>
)}
{projectMetrics && AdminItemIsProject(adminItem) && (
<RecentProjectMetrics
project={adminItem}
projectMetrics={projectMetrics}
onSelectUser={selectItem}
onDismiss={() => router.back()}
/>
)}
{workspaceMetrics && (
<RecentWorkspaceMetrics
workspaceMetrics={workspaceMetrics}
onSelectUser={selectItem}
onSelectProject={selectItem}
onDismiss={() => router.back()}
/>
)}
</div>
)
}
11 changes: 6 additions & 5 deletions components/chains/chainEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { ChainNode, IsBranchChainItem } from './chainNode'
import ChainEditorHeader from './chainEditorHeader'
import SegmentedControl, { Segment } from '../segmentedControl'
import { ChainPromptCache } from '@/src/client/hooks/useChainPromptCache'
import { ChainItemCache } from '@/src/client/hooks/useChainItemCache'
import { Fragment, useState } from 'react'
import { useCheckProviders } from '@/src/client/context/providerContext'
import { EmbeddingModels, QueryProviders } from '@/src/common/providerMetadata'
Expand All @@ -33,7 +33,7 @@ export default function ChainEditor({
isTestMode,
setTestMode,
disabled,
promptCache,
itemCache,
}: {
chain: ActiveChain
activeVersion: ChainVersion
Expand All @@ -49,7 +49,7 @@ export default function ChainEditor({
isTestMode: boolean
setTestMode: (testMode: boolean) => void
disabled: boolean
promptCache: ChainPromptCache
itemCache: ChainItemCache
}) {
const [checkProviderAvailable, checkModelAvailable] = useCheckProviders()
const provider = QueryProviders.find(provider => checkProviderAvailable(provider))
Expand Down Expand Up @@ -89,7 +89,7 @@ export default function ChainEditor({
const insertPrompt = (index: number, branch: number, promptID: number, versionID?: number) =>
insertItem(index, branch, {
promptID,
versionID: versionID ?? promptCache.versionForItem({ promptID })?.id,
versionID: versionID ?? itemCache.versionForItem({ promptID })?.id,
})

const insertNewPrompt = (index: number, branch: number) =>
Expand Down Expand Up @@ -145,7 +145,7 @@ export default function ChainEditor({
savedVersion={isVersionSaved ? activeVersion : null}
setTestMode={setTestMode}
prompts={prompts}
promptCache={promptCache}
itemCache={itemCache}
/>
{<StartBranchConnector row={row} maxBranch={maxBranch} nodes={nodes} colSpans={colSpans} />}
{rowIndex < rows.length - 1 && (
Expand All @@ -154,6 +154,7 @@ export default function ChainEditor({
previousRow={row}
nextRow={rows[rowIndex + 1]}
maxBranch={maxBranch}
maxNonLoopingBranch={maxNonLoopingBranch}
prompts={prompts}
isDisabled={isTestMode}
activeMenuIndex={activeMenuIndex}
Expand Down
18 changes: 11 additions & 7 deletions components/chains/chainEditorRow.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ActiveChain, ChainItem, ChainVersion, Prompt } from '@/types'
import { ChainNode, IsBranchChainItem, IsChainItem } from './chainNode'
import { ChainNodeBox } from './chainNodeBox'
import { ChainPromptCache } from '@/src/client/hooks/useChainPromptCache'
import { ChainItemCache } from '@/src/client/hooks/useChainItemCache'
import { FirstBranchForBranchOfNode, ShouldBranchLoopOnCompletion } from '@/src/common/branching'
import ChainNodeBoxConnector, { DownConnector, DownStroke } from './chainNodeBoxConnector'
import ChainNodeBoxConnector, { DownArrow, DownStroke } from './chainNodeBoxConnector'

export type InsertActions = {
insertItem: (index: number, branch: number, item: ChainItem) => void
Expand Down Expand Up @@ -45,6 +45,7 @@ const shouldBranchLoopOnCompletion = (nodes: ChainNode[], branch: number) =>
export const ConnectorRow = (props: {
nodes: ChainNode[]
maxBranch: number
maxNonLoopingBranch: number
previousRow: ChainNode[]
nextRow: ChainNode[]
isDisabled: boolean
Expand All @@ -63,6 +64,7 @@ export const ConnectorRow = (props: {
const ConnectorCell = ({
nodes,
branch,
maxNonLoopingBranch,
previousRow,
nextRow,
isDisabled,
Expand All @@ -73,6 +75,7 @@ const ConnectorCell = ({
}: {
nodes: ChainNode[]
branch: number
maxNonLoopingBranch: number
previousRow: ChainNode[]
nextRow: ChainNode[]
isDisabled: boolean
Expand Down Expand Up @@ -104,6 +107,7 @@ const ConnectorCell = ({
hasPrevious={!!precedingNode && !IsBranchChainItem(precedingNode)}
hasNext={!!nextNode && IsChainItem(nextNode)}
hasCompleted={hasCompletedBranch}
hasEndBranchConnector={maxNonLoopingBranch > 0}
{...bindInsertActions(insertActions, index, branch)}
/>
) : didStartBranchInColumn(nodes, previousNodeIndex, branch) && !hasCompletedBranch ? (
Expand All @@ -127,7 +131,7 @@ export const NodesRow = (props: {
savedVersion: ChainVersion | null
setTestMode: (testMode: boolean) => void
prompts: Prompt[]
promptCache: ChainPromptCache
itemCache: ChainItemCache
}) => (
<>
{Array.from({ length: props.maxBranch + 1 }, (_, branch) => (
Expand All @@ -150,7 +154,7 @@ const NodeCell = ({
savedVersion,
setTestMode,
prompts,
promptCache,
itemCache,
}: {
chain: ActiveChain
nodes: ChainNode[]
Expand All @@ -165,7 +169,7 @@ const NodeCell = ({
savedVersion: ChainVersion | null
setTestMode: (testMode: boolean) => void
prompts: Prompt[]
promptCache: ChainPromptCache
itemCache: ChainItemCache
}) => {
const firstNodeOfRowIndex = nodes.indexOf(row[0])
const isLastRow = firstNodeOfRowIndex === nodes.length - 1
Expand Down Expand Up @@ -216,7 +220,7 @@ const NodeCell = ({
savedVersion={savedVersion}
setTestMode={setTestMode}
prompts={prompts}
promptCache={promptCache}
itemCache={itemCache}
/>
)
) : !isLastRow && !hasCompletedBranch && didStartBranchInColumn(nodes, firstNodeOfRowIndex, branch) ? (
Expand Down Expand Up @@ -291,7 +295,7 @@ export const EndBranchConnector = ({
/>
<RowFiller start={maxNonLoopingBranch + 1} end={maxBranch} colSpans={colSpans} />
<div className='flex flex-col items-center'>
<DownConnector height='min-h-[18px]' />
<DownArrow height='min-h-[18px]' />
</div>
<RowFiller start={1} end={maxBranch} colSpans={colSpans} />
</>
Expand Down
16 changes: 8 additions & 8 deletions components/chains/chainItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import {
IsQueryChainItem,
SubtreeForChainNode,
} from './chainNode'
import { ChainPromptCache } from '../../src/client/hooks/useChainPromptCache'
import { ChainItemCache } from '../../src/client/hooks/useChainItemCache'
import { ExtractCodeInterrupts, ExtractPromptVariables, ExtractVariables } from '@/src/common/formatting'

export const GetChainItemsSaveKey = (items: ChainItem[]) => JSON.stringify(stripItemsToSave(items))

export const GetItemsToSave = (items: ChainItem[], promptCache: ChainPromptCache) =>
augmentItemsToSave(stripItemsToSave(items), promptCache)
export const GetItemsToSave = (items: ChainItem[], itemCache: ChainItemCache) =>
augmentItemsToSave(stripItemsToSave(items), itemCache)

const stripItemsToSave = (items: ChainItem[]): ChainItem[] =>
items.map(item => {
Expand All @@ -26,19 +26,19 @@ const stripItemsToSave = (items: ChainItem[]): ChainItem[] =>
}
})

const augmentItemsToSave = (items: ChainItem[], promptCache: ChainPromptCache) =>
const augmentItemsToSave = (items: ChainItem[], itemCache: ChainItemCache) =>
items.map(item => {
const inputs = ExtractChainItemVariables(item, promptCache, false)
const inputs = ExtractChainItemVariables(item, itemCache, false)
return IsCodeChainItem(item) || IsBranchChainItem(item) || IsQueryChainItem(item)
? { ...item, inputs }
: {
...item,
inputs,
dynamicInputs: ExtractChainItemVariables(item, promptCache, true).filter(input => !inputs.includes(input)),
dynamicInputs: ExtractChainItemVariables(item, itemCache, true).filter(input => !inputs.includes(input)),
}
})

export const ExtractChainItemVariables = (item: ChainItem, cache: ChainPromptCache, includingDynamic: boolean) => {
export const ExtractChainItemVariables = (item: ChainItem, cache: ChainItemCache, includingDynamic: boolean) => {
if (IsCodeChainItem(item) || IsBranchChainItem(item)) {
return [...ExtractVariables(item.code), ...(includingDynamic ? ExtractCodeInterrupts(item.code) : [])]
}
Expand All @@ -56,7 +56,7 @@ const extractChainItemInputs = (item: ChainItem, includingDynamic: boolean) => [
...(includingDynamic && IsPromptChainItem(item) ? item.dynamicInputs ?? [] : []),
]

export const ExtractUnboundChainVariables = (chain: ChainItem[], cache: ChainPromptCache, includingDynamic: boolean) =>
export const ExtractUnboundChainVariables = (chain: ChainItem[], cache: ChainItemCache, includingDynamic: boolean) =>
excludeBoundChainVariables(
chain.map(item => ({ ...item, inputs: ExtractChainItemVariables(item, cache, includingDynamic) }))
)
Expand Down
6 changes: 3 additions & 3 deletions components/chains/chainNode.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LoopCompletionIndexForNode, ShouldBranchLoopOnCompletion, SubtreeForNode } from '@/src/common/branching'
import { BranchChainItem, ChainItem, CodeChainItem, PromptChainItem, QueryChainItem } from '@/types'
import { ChainPromptCache } from '@/src/client/hooks/useChainPromptCache'
import { ChainItemCache } from '@/src/client/hooks/useChainItemCache'
import { ExtractChainItemVariables } from './chainItems'

export const InputNode = 'input'
Expand Down Expand Up @@ -54,11 +54,11 @@ export const CanChainNodeIncludeContext = (chainNode: ChainNode, nodes: ChainNod
export const MappableTargetInputsForChainNode = (
chainNode: ChainNode,
nodes: ChainNode[],
promptCache: ChainPromptCache
itemCache: ChainItemCache
): string[] => [
...new Set(
SubtreeForChainNode(chainNode, nodes, false, true).flatMap(item =>
ExtractChainItemVariables(item, promptCache, false)
ExtractChainItemVariables(item, itemCache, false)
)
),
]
10 changes: 5 additions & 5 deletions components/chains/chainNodeBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ActiveChain, BranchChainItem, ChainItem, ChainVersion, Prompt } from '@/types'
import { ChainNode, InputNode, IsBranchChainItem, IsChainItem, OutputNode } from './chainNode'
import { ChainPromptCache } from '@/src/client/hooks/useChainPromptCache'
import { ChainItemCache } from '@/src/client/hooks/useChainItemCache'
import ChainNodeBoxHeader from './chainNodeBoxHeader'
import ChainNodeBoxBody from './chainNodeBoxBody'
import ChainNodeBoxFooter from './chainNodeBoxFooter'
Expand All @@ -19,7 +19,7 @@ export function ChainNodeBox({
savedVersion,
setTestMode,
prompts,
promptCache,
itemCache,
}: {
chain: ActiveChain
index: number
Expand All @@ -31,7 +31,7 @@ export function ChainNodeBox({
savedVersion: ChainVersion | null
setTestMode: (testMode: boolean) => void
prompts: Prompt[]
promptCache: ChainPromptCache
itemCache: ChainItemCache
}) {
const chainNode = nodes[index]
const isSelected = index === activeIndex
Expand Down Expand Up @@ -98,13 +98,13 @@ export function ChainNodeBox({
prompts={prompts}
users={chain.users}
/>
<ChainNodeBoxBody chainNode={chainNode} items={items} isSelected={isSelected} promptCache={promptCache} />
<ChainNodeBoxBody chainNode={chainNode} items={items} isSelected={isSelected} itemCache={itemCache} />
<ChainNodeBoxFooter
nodes={nodes}
index={index}
onUpdate={updateItem}
isSelected={isSelected}
promptCache={promptCache}
itemCache={itemCache}
/>
{chainNode !== OutputNode && <SmallDot position='bottom' />}
</div>
Expand Down
Loading

0 comments on commit 2b0ffc3

Please sign in to comment.