Skip to content

Commit

Permalink
feature: dynamic docs (#274)
Browse files Browse the repository at this point in the history
Adds documentation in the prompt section so that users can easily
integrate their prompt in their environments via sdk.
  • Loading branch information
geclos authored Sep 25, 2024
1 parent 62db4dd commit dbec1c3
Show file tree
Hide file tree
Showing 16 changed files with 612 additions and 36 deletions.
8 changes: 8 additions & 0 deletions apps/web/src/app/(private)/_data-access/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { cache } from 'react'
import { type Commit } from '@latitude-data/core/browser'
import { findAllEvaluationTemplates } from '@latitude-data/core/data-access'
import { NotFoundError } from '@latitude-data/core/lib/errors'
import { ApiKeysRepository } from '@latitude-data/core/repositories/apiKeysRepository'
import {
CommitsRepository,
ConnectedEvaluationsRepository,
Expand Down Expand Up @@ -222,3 +223,10 @@ export const getConnectedDocumentsWithMetadataCached = cache(
return result.unwrap()
},
)

export const getApiKeysCached = cache(async () => {
const { workspace } = await getCurrentUser()
const scope = new ApiKeysRepository(workspace.id)
const result = await scope.findAll()
return result.unwrap()
})
1 change: 0 additions & 1 deletion apps/web/src/app/(private)/_lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ export const MAIN_NAV_LINKS = [
{ label: 'Projects', value: ROUTES.dashboard.root as DocumentRoutes },
{ label: 'Evaluations', value: ROUTES.evaluations.root as DocumentRoutes },
{ label: 'Datasets', value: ROUTES.datasets.root as DocumentRoutes },
{ label: 'Settings', value: ROUTES.settings.root as DocumentRoutes },
]
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default function DocumentEditor({
documentUuid: document.documentUuid,
content: val,
})

setIsSaved(true)
},
500,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { ReactNode } from 'react'
'use client'

import { ReactNode, useContext } from 'react'

import { Button, Icon } from '@latitude-data/web-ui'

import { DocumentationContext } from '../DocumentationModal'
import { DocumentTabSelector } from './tabs'

export default function DocumentTabs({
Expand All @@ -9,13 +14,19 @@ export default function DocumentTabs({
params: { documentUuid: string; projectId: string; commitUuid: string }
children: ReactNode
}) {
const { toggleDocumentation } = useContext(DocumentationContext)
return (
<div className='flex flex-col h-full'>
<DocumentTabSelector
projectId={params.projectId}
commitUuid={params.commitUuid}
documentUuid={params.documentUuid}
/>
<div className='flex flex-row items-center justify-between pt-6 px-4'>
<DocumentTabSelector
projectId={params.projectId}
commitUuid={params.commitUuid}
documentUuid={params.documentUuid}
/>
<Button variant='ghost' onClick={toggleDocumentation}>
Deploy this prompt <Icon name='code2' />
</Button>
</div>
<div className='flex-grow flex flex-col w-full overflow-hidden'>
{children}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,16 @@ export function DocumentTabSelector({
}

return (
<div className='flex flex-row p-4 pt-6 pb-0'>
<TabSelector
options={[
{ label: 'Editor', value: DocumentRoutes.editor },
{ label: 'Evaluations', value: DocumentRoutes.evaluations },
{ label: 'Logs', value: DocumentRoutes.logs },
]}
selected={selectedSegment ?? DocumentRoutes.editor}
onSelect={(value) => {
router.push(pathTo(value))
}}
/>
</div>
<TabSelector
options={[
{ label: 'Editor', value: DocumentRoutes.editor },
{ label: 'Evaluations', value: DocumentRoutes.evaluations },
{ label: 'Logs', value: DocumentRoutes.logs },
]}
selected={selectedSegment ?? DocumentRoutes.editor}
onSelect={(value) => {
router.push(pathTo(value))
}}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { CodeBlock, Text } from '@latitude-data/web-ui'

export function APIUsage({
projectId,
commitUuid,
documentPath,
apiKey,
parameters,
}: {
projectId: number
commitUuid: string
documentPath: string
apiKey: string | undefined
parameters: Set<string>
}) {
const getRequestBodyContent = () => {
const bodyContent = [` "path": "${documentPath}"`]

if (parameters.size > 0) {
const parameterEntries = Array.from(parameters)
.map((key) => ` "${key}": ""`)
.join(',\n')

bodyContent.push(` "parameters": {
${parameterEntries}
}`)
}

return bodyContent.join(',\n')
}

const apiCode = `
curl -X POST \\
https://api.latitude.io/v1/projects/${projectId}/versions/${commitUuid}/documents/run \\
-H 'Authorization: Bearer ${apiKey ?? 'YOUR_API_KEY'}' \\
-H 'Content-Type: application/json' \\
-d '{
${getRequestBodyContent()}
}'
`

return (
<div className='flex flex-col gap-4'>
<Text.H4>You can use the Latitude API to run this document:</Text.H4>
<CodeBlock language='bash'>{apiCode.trim()}</CodeBlock>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react'

import { HEAD_COMMIT } from '@latitude-data/core/browser'
import { CodeBlock, Text } from '@latitude-data/web-ui'

export function JavascriptUsage({
projectId,
commitUuid,
documentPath,
apiKey,
parameters,
}: {
projectId: number
commitUuid: string
documentPath: string
apiKey: string | undefined
parameters: Set<string>
}) {
const getParametersString = () => {
if (parameters.size === 0) return ''

const parameterEntries = Array.from(parameters)
.map((key) => ` ${key}: ''`)
.join(',\n')

return ` parameters: {
${parameterEntries}
}`
}

const getRunOptions = () => {
const options = []

if (commitUuid !== HEAD_COMMIT) {
options.push(` versionUuid: '${commitUuid}'`)
}

const parametersString = getParametersString()
if (parametersString) {
options.push(parametersString)
}

return options.length > 0 ? `{\n${options.join(',\n')}\n}` : ''
}

const sdkCode = `import { Latitude } from '@latitude-data/sdk'
// Do not expose the API key in client-side code
const sdk = new Latitude('${apiKey ?? 'YOUR_API_KEY'}', { projectId: ${projectId} })
const result = await sdk.run('${documentPath}'${getRunOptions() ? `, ${getRunOptions()}` : ''})
`

return (
<div className='flex flex-col gap-4'>
<Text.H4>
To run this document programmatically, First install the SDK:
</Text.H4>
<CodeBlock language='bash'>npm install @latitude-data/sdk</CodeBlock>
<Text.H4>Then, use the following code to run the document:</Text.H4>
<CodeBlock language='typescript'>{sdkCode}</CodeBlock>
<Text.H4>
Check out{' '}
<a
target='_blank'
className='text-primary underline'
href='https://docs.latitude.so'
>
our docs
</a>{' '}
for more details.
</Text.H4>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
'use client'

import React, { useState } from 'react'

import { ApiKey, DocumentVersion } from '@latitude-data/core/browser'

import { APIUsage } from './APIUsage'
import { JavascriptUsage } from './JavascriptUsage'

type TabItem = {
id: string
label: string
}

const Tabs: React.FC<{
tabs: TabItem[]
activeTab: string
onChange: (tabId: string) => void
}> = ({ tabs, activeTab, onChange }) => {
return (
<div className='flex border-b border-gray-200'>
{tabs.map((tab) => (
<button
key={tab.id}
className={`px-4 py-2 font-medium ${
activeTab === tab.id
? 'border-b-2 border-primary text-primary'
: 'text-muted-foreground'
}`}
onClick={() => onChange(tab.id)}
>
{tab.label}
</button>
))}
</div>
)
}

const tabs: TabItem[] = [
{ id: 'sdk', label: 'Javascript' },
{ id: 'api', label: 'HTTP API' },
]

interface SettingsTabsProps {
projectId: number
commitUuid: string
document: DocumentVersion
apiKeys: ApiKey[]
parameters: Set<string>
}

export function SettingsTabs({
projectId,
commitUuid,
document,
apiKeys,
parameters,
}: SettingsTabsProps) {
const [activeTab, setActiveTab] = useState('sdk')

return (
<div className='flex flex-col gap-4 border rounded-lg min-w-0'>
<Tabs
tabs={tabs}
activeTab={activeTab}
onChange={(tabId) => setActiveTab(tabId)}
/>
<div className='p-4'>
{activeTab === 'sdk' && (
<JavascriptUsage
apiKey={apiKeys[0]?.token}
projectId={projectId}
commitUuid={commitUuid}
documentPath={document.path}
parameters={parameters}
/>
)}
{activeTab === 'api' && (
<APIUsage
apiKey={apiKeys[0]?.token}
projectId={projectId}
commitUuid={commitUuid}
documentPath={document.path}
parameters={parameters}
/>
)}
</div>
</div>
)
}
Loading

0 comments on commit dbec1c3

Please sign in to comment.