Skip to content
5 changes: 5 additions & 0 deletions server/api/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ export const agentAnalysisQuerySchema = z.object({
workspaceExternalId: z.string().optional(),
})

// Schema for connector ID parameter
export const connectorIdParamsSchema = z.object({
connectorId: z.string().min(1),
})

export const GetConnectors = async (c: Context) => {
const { workspaceId, sub } = c.get(JwtPayloadKey)
const users: SelectUser[] = await getUserByEmail(db, sub)
Expand Down
13 changes: 11 additions & 2 deletions server/api/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ export const listAgentsSchema = z.object({
filter: z.enum(["all", "madeByMe", "sharedToMe"]).optional().default("all"),
})

export const getAgentParamsSchema = z.object({
agentExternalId: z.string().min(1),
})

export const generatePromptQuerySchema = z.object({
requirements: z.string().min(1, "Requirements are required"),
modelId: z.string().optional(),
})

export const safeGet = <T>(c: Context, key: string): T | undefined => {
try {
return c.get(key) as T
Expand Down Expand Up @@ -514,8 +523,8 @@ export const GetWorkspaceUsersApi = async (c: Context) => {
.where(
and(
eq(users.workspaceId, userAndWorkspace.workspace.id),
isNull(users.deletedAt)
)
isNull(users.deletedAt),
),
)

return c.json(workspaceUsers)
Expand Down
12 changes: 12 additions & 0 deletions server/api/dataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@ export const deleteDocumentSchema = z.object({
schema: z.string().min(1),
})

export const getDataSourceFileParamsSchema = z.object({
docId: z.string().min(1),
})

export const listDataSourceFilesParamsSchema = z.object({
dataSourceName: z.string().min(1),
})

export const getAgentsForDataSourceParamsSchema = z.object({
dataSourceId: z.string().min(1),
})

export const DeleteImages = async (docId: string) => {
const imageDir = path.resolve(
process.env.IMAGE_DIR || "downloads/xyne_images_db",
Expand Down
92 changes: 85 additions & 7 deletions server/api/knowledgeBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ const MAX_ZIP_FILE_SIZE = 35 // 35MB max zip file size
}
})()

// Duplicate handling strategies
enum DuplicateStrategy {
SKIP = "skip",
RENAME = "rename",
OVERWRITE = "overwrite",
}

// Schema definitions for Knowledge Base feature
const createCollectionSchema = z.object({
name: z.string().min(1).max(255),
Expand All @@ -144,6 +151,84 @@ const createFolderSchema = z.object({
metadata: z.record(z.any(), z.any()).optional(),
})

const pollCollectionsStatusSchema = z.object({
collectionIds: z.array(z.string()).min(1),
})

const collectionParamsSchema = z.object({
clId: z.string().min(1),
})

const collectionNameForSharedAgentParamsSchema = z.object({
clId: z.string().min(1),
})

const collectionNameForSharedAgentQuerySchema = z.object({
agentExternalId: z.string().min(1),
})

const listCollectionItemsParamsSchema = z.object({
clId: z.string().min(1),
})

const listCollectionItemsQuerySchema = z.object({
parentId: z.string().optional(),
})

const deleteItemParamsSchema = z.object({
clId: z.string().min(1),
itemId: z.string().min(1),
})

const fileOperationParamsSchema = z.object({
clId: z.string().min(1),
itemId: z.string().min(1),
})

const chunkContentParamsSchema = z.object({
cId: z.string().min(1),
docId: z.string().min(1),
})

const listCollectionsQuerySchema = z.object({
ownOnly: z.string().optional(),
includeItems: z.string().optional(),
})

// Form schemas for file upload endpoints
// Note: 'files' and 'paths' fields are validated manually in the handler
// because they are File objects and string arrays that can't be effectively
// validated with Zod schemas (size, MIME type, binary content validation required)
const uploadFilesFormSchema = z.object({
parentId: z.string().optional().nullable(),
duplicateStrategy: z
.enum([
DuplicateStrategy.SKIP,
DuplicateStrategy.RENAME,
DuplicateStrategy.OVERWRITE,
])
.optional(),
sessionId: z.string().optional().nullable(),
})

// Export schemas for use in server.ts
export {
createCollectionSchema,
updateCollectionSchema,
createFolderSchema,
pollCollectionsStatusSchema,
collectionParamsSchema,
collectionNameForSharedAgentParamsSchema,
collectionNameForSharedAgentQuerySchema,
listCollectionItemsParamsSchema,
listCollectionItemsQuerySchema,
deleteItemParamsSchema,
fileOperationParamsSchema,
chunkContentParamsSchema,
listCollectionsQuerySchema,
uploadFilesFormSchema,
}

// Helper functions
function calculateChecksum(buffer: ArrayBuffer): string {
const hash = crypto.createHash("sha256")
Expand Down Expand Up @@ -952,13 +1037,6 @@ export const CreateFolderApi = async (c: Context) => {
}
}

// Duplicate handling strategies
enum DuplicateStrategy {
SKIP = "skip",
RENAME = "rename",
OVERWRITE = "overwrite",
}

// Helper function to generate unique name
function generateUniqueName(baseName: string, existingNames: string[]): string {
const nameLower = baseName.toLowerCase()
Expand Down
20 changes: 15 additions & 5 deletions server/api/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,13 @@ export const messageSchema = z.object({
if (!val) return false
return val.toLowerCase() === "true"
}),
isFollowUp: z.string().optional().transform((val) => {
if (!val) return false
return val.toLowerCase() === "true"
}),
isFollowUp: z
.string()
.optional()
.transform((val) => {
if (!val) return false
return val.toLowerCase() === "true"
}),
})

export type MessageReqType = z.infer<typeof messageSchema>
Expand Down Expand Up @@ -255,6 +258,13 @@ export const generatePromptSchema = z.object({
),
})

export const getDriveItemSchema = z.object({
parentId: z.string().optional(),
})

export const getDriveItemsByDocIdsSchema = z.object({
docIds: z.array(z.string()).min(1, "At least one docId is required"),
})

export const handleAttachmentDeleteSchema = z.object({
attachment: attachmentMetadataSchema,
Expand Down Expand Up @@ -306,7 +316,7 @@ export const SearchApi = async (c: Context) => {
debug,
agentId,
// @ts-ignore
} = c.req.valid("query")
} = c.req.valid("query")
let groupCount: any = {}
let results: VespaSearchResponse = {} as VespaSearchResponse
const timestampRange = getTimestamp(lastUpdated)
Expand Down
20 changes: 14 additions & 6 deletions server/api/testEmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@ import { type Context } from "hono"
import { emailService } from "@/services/emailService"
import { getLogger } from "@/logger"
import { Subsystem } from "@/types"
import { z } from "zod"

const Logger = getLogger(Subsystem.Server)

export const sendEmailSchema = z.object({
email: z.string(),
subject: z.string().optional(),
body: z.string().optional(),
})

export const sendMailHelper = async (c: Context) => {
try {
Logger.info("Testing email sending...")

if (process.env.NODE_ENV !== "production") {
Logger.debug("SES env debug", {
awsAccessKeyIdPrefix: process.env.SES_AWS_ACCESS_KEY_ID?.slice(0, 4) ?? "unset",
awsRegion: process.env.SES_AWS_REGION ?? "unset",
sesFromEmail: process.env.SES_FROM_EMAIL ?? "unset",
})
}
Logger.debug("SES env debug", {
awsAccessKeyIdPrefix:
process.env.SES_AWS_ACCESS_KEY_ID?.slice(0, 4) ?? "unset",
awsRegion: process.env.SES_AWS_REGION ?? "unset",
sesFromEmail: process.env.SES_FROM_EMAIL ?? "unset",
})
}
const { email, body, subject } = await c.req.json()

if (!email) {
Expand Down
10 changes: 10 additions & 0 deletions server/api/tuning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ export const evaluateSchema = z.object({
// Add other controllable parameters here in the future
})

// Zod schema for delete dataset endpoint
export const deleteDatasetParamsSchema = z.object({
filename: z.string().min(1),
})

// Zod schema for tuning WebSocket route
export const tuningWsParamsSchema = z.object({
jobId: z.string().min(1),
})

// --- Helper Functions Adapted from Script ---

// Fetch random document from Vespa (adapted for API context)
Expand Down
Loading