Skip to content

Commit

Permalink
feat: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
andresgutgon committed Dec 19, 2024
1 parent 29198b6 commit e2833ce
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 11 deletions.
149 changes: 149 additions & 0 deletions apps/gateway/src/common/documents/getData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { omit } from 'lodash-es'

import { Message } from '@latitude-data/compiler'
import {
Commit,
DocumentVersion,
Project,
type Workspace,
} from '@latitude-data/core/browser'
import { findFirstUserInWorkspace } from '@latitude-data/core/data-access'
import { publisher } from '@latitude-data/core/events/publisher'
import { BadRequestError } from '@latitude-data/core/lib/errors'
import { Result } from '@latitude-data/core/lib/Result'
import {
CommitsRepository,
DocumentVersionsRepository,
ProjectsRepository,
} from '@latitude-data/core/repositories'
import { Config } from '@latitude-data/core/services/ai/helpers'
import {
ChainCallResponseDto,
ChainEvent,
ChainEventDto,
ChainEventTypes,
LatitudeEventData,
StreamEventTypes,
} from '@latitude-data/constants'

export const getData = async ({
workspace,
projectId,
commitUuid,
documentPath,
}: {
workspace: Workspace
projectId: number
commitUuid: string
documentPath: string
}) => {
const projectsScope = new ProjectsRepository(workspace.id)
const commitsScope = new CommitsRepository(workspace.id)
const docsScope = new DocumentVersionsRepository(workspace.id)

const pid = Number(projectId)
if (isNaN(pid)) {
return Result.error(new BadRequestError(`Invalid project id ${projectId}`))
}

const projectResult = await projectsScope.getProjectById(pid)
if (projectResult.error) return projectResult
const project = projectResult.value

const commitResult = await commitsScope.getCommitByUuid({
projectId: project.id,
uuid: commitUuid,
})
if (commitResult.error) return commitResult
const commit = commitResult.value

const documentResult = await docsScope.getDocumentByPath({
commit,
path: documentPath,
})
if (documentResult.error) return documentResult
const document = documentResult.value

return Result.ok({ project, commit, document })
}

export function chainEventPresenter(event: ChainEvent) {
switch (event.event) {
case StreamEventTypes.Provider:
return event.data
case StreamEventTypes.Latitude:
return latitudeEventPresenter(event)
}
}

function latitudeEventPresenter(event: {
data: LatitudeEventData
event: StreamEventTypes.Latitude
}): ChainEventDto | string {
switch (event.data.type) {
case ChainEventTypes.Step:
case ChainEventTypes.StepComplete:
return {
...omit(event.data, 'documentLogUuid'),
uuid: event.data.documentLogUuid!,
} as {
type: ChainEventTypes.Step
config: Config
isLastStep: boolean
messages: Message[]
uuid?: string
}
case ChainEventTypes.Complete:
return {
...omit(event.data, 'documentLogUuid'),
uuid: event.data.response.documentLogUuid!,
response: omit(
event.data.response,
'providerLog',
'documentLogUuid',
) as ChainCallResponseDto,
}
case ChainEventTypes.Error:
return {
type: ChainEventTypes.Error,
error: {
name: event.data.error.name,
message: event.data.error.message,
stack: event.data.error.stack,
},
}
default:
throw new BadRequestError(
`Unknown event type in chainEventPresenter ${JSON.stringify(event)}`,
)
}
}

export async function publishDocumentRunRequestedEvent({
workspace,
project,
commit,
document,
parameters,
}: {
workspace: Workspace
project: Project
commit: Commit
document: DocumentVersion
parameters: Record<string, any>
}) {
const user = await findFirstUserInWorkspace(workspace)
if (user) {
publisher.publishLater({
type: 'documentRunRequested',
data: {
parameters,
projectId: project.id,
commitUuid: commit.uuid,
documentPath: document.path,
workspaceId: workspace.id,
userEmail: user.email,
},
})
}
}
5 changes: 2 additions & 3 deletions apps/gateway/src/presenters/documentPresenter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
Commit,
configSchema,
DocumentVersion,
Providers,
Workspace,
Expand All @@ -13,8 +12,8 @@ export const documentPresenterSchema = z.object({
uuid: z.string(),
path: z.string(),
content: z.string(),
config: configSchema.optional(),
provider: z.nativeEnum(Providers).or(z.undefined()),
config: z.object({}).passthrough(),
provider: z.nativeEnum(Providers).optional()
})


Expand Down
3 changes: 3 additions & 0 deletions apps/gateway/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ const DOCUMENTS = `${VERSION_DETAIL}/documents`
export const ROUTES = {
v2: {
documents: {
get: `${DOCUMENTS}/{documentPath}`,
getOrCreate: `${DOCUMENTS}/get-or-create`,
run: `${DOCUMENTS}/run`,
logs: `${DOCUMENTS}/logs`,
},
},
}
8 changes: 7 additions & 1 deletion apps/gateway/src/routes/v2/documents/documents.index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { createRouter } from '$/openApi/createApp'

import { runHandler, runRoute } from '$/routes/v2/documents/run'
import {
getOrCreateHandler,
getOrCreateRoute,
} from '$/routes/v2/documents/getOrCreate'

const router = createRouter().openapi(runRoute, runHandler)
const router = createRouter()
.openapi(runRoute, runHandler)
.openapi(getOrCreateRoute, getOrCreateHandler)

export default router
19 changes: 19 additions & 0 deletions apps/gateway/src/routes/v2/documents/get/get.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getData } from '$/common/documents/getData'
import { AppRouteHandler } from '$/openApi/types'
import { documentPresenter } from '$/presenters/documentPresenter'
import { GetRoute } from '$/routes/v2/documents/get/get.route'

// @ts-expect-error: broken types
export const getHandler: AppRouteHandler<GetRoute> = async (c) => {
const workspace = c.get('workspace')
const { projectId, versionUuid, documentPath } = c.req.valid('param')
const { document, commit } = await getData({
workspace,
projectId: Number(projectId!),
commitUuid: versionUuid!,
documentPath: documentPath!,
}).then((r) => r.unwrap())

const data = await documentPresenter({ document, commit, workspace })
return c.json(data, 200)
}
31 changes: 31 additions & 0 deletions apps/gateway/src/routes/v2/documents/get/get.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import http from '$/common/http'
import { GENERIC_ERROR_RESPONSES } from '$/openApi/responses/errorResponses'
import { documentPresenterSchema } from '$/presenters/documentPresenter'
import { ROUTES } from '$/routes'
import { documentParamsSchema } from '$/routes/v2/documents/paramsSchema'
import { createRoute, z } from '@hono/zod-openapi'

export const getRoute = createRoute({
operationId: 'getDocument',
method: http.Methods.POST,
path: ROUTES.v2.documents.get,
tags: ['Documents'],
request: {
params: documentParamsSchema.extend({
documentPath: z.string().openapi({
description: 'Prompt path',
}),
}),
},
responses: {
...GENERIC_ERROR_RESPONSES,
[http.Status.OK]: {
description: 'The document was created or retrieved successfully',
content: {
[http.MediaTypes.JSON]: { schema: documentPresenterSchema },
},
},
},
})

export type GetRoute = typeof getRoute
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ async function getOrCreateDocument({
}).then((r) => r.unwrap())
}

// @ts-expect-error: Types are not working as expected
export const getOrCreateHandler: AppRouteHandler<GetOrCreateRoute> = async (
c,
) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ import { documentParamsSchema } from '$/routes/v2/documents/paramsSchema'
import { createRoute, z } from '@hono/zod-openapi'

export const getOrCreateRoute = createRoute({
operationId: 'getOrCreateDocument',
method: http.Methods.POST,
path: ROUTES.v2.documents.run,
path: ROUTES.v2.documents.getOrCreate,
tags: ['Documents'],
request: {
params: documentParamsSchema,
body: {
content: {
[http.MediaTypes.JSON]: {
schema: z.object({
path: z
.string()
.openapi({ description: 'Desired path for the prompt' }),
prompt: z.string().optional().openapi({
description: 'The prompt to use for the new document',
}),
path: z.string(),
prompt: z.string().optional(),
}),
},
},
Expand Down
1 change: 1 addition & 0 deletions apps/gateway/src/routes/v2/documents/run/run.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
export const runRoute = createRoute({
method: http.Methods.POST,
path: ROUTES.v2.documents.run,
tags: ['Documents'],
request: {
params: documentParamsSchema,
body: {
Expand Down

0 comments on commit e2833ce

Please sign in to comment.