103 lines
4.0 KiB
TypeScript
103 lines
4.0 KiB
TypeScript
import { tool } from 'ai'
|
|
import { z } from 'zod'
|
|
import type { Payload, PayloadRequest, User } from 'payload'
|
|
|
|
export const generatePayloadLocalTools = (
|
|
payload: Payload,
|
|
req: PayloadRequest,
|
|
allowedCollections: string[]
|
|
) => {
|
|
const tools: Record<string, any> = {}
|
|
|
|
for (const collectionSlug of allowedCollections) {
|
|
const slugKey = collectionSlug.replace(/-/g, '_')
|
|
|
|
// 1. Read (Find) Tool
|
|
tools[`read_${slugKey}`] = tool({
|
|
description: `Read/Find documents from the Payload CMS collection: ${collectionSlug}`,
|
|
parameters: z.object({
|
|
limit: z.number().optional().describe('Number of documents to return, max 100.'),
|
|
page: z.number().optional().describe('Page number for pagination.'),
|
|
// Simple string-based query for demo purposes. For a robust implementation,
|
|
// we'd map this to Payload's where query logic using a structured Zod schema.
|
|
query: z.string().optional().describe('Optional text to search within the collection.'),
|
|
}),
|
|
execute: async ({ limit = 10, page = 1, query }) => {
|
|
const where = query ? { id: { equals: query } } : undefined // Placeholder logic
|
|
|
|
return await payload.find({
|
|
collection: collectionSlug as any,
|
|
limit: Math.min(limit, 100),
|
|
page,
|
|
where,
|
|
req, // Crucial for passing the user context and respecting access control!
|
|
})
|
|
},
|
|
})
|
|
|
|
// 2. Read by ID Tool
|
|
tools[`read_${slugKey}_by_id`] = tool({
|
|
description: `Get a specific document by its ID from the ${collectionSlug} collection.`,
|
|
parameters: z.object({
|
|
id: z.union([z.string(), z.number()]).describe('The ID of the document.'),
|
|
}),
|
|
execute: async ({ id }) => {
|
|
return await payload.findByID({
|
|
collection: collectionSlug as any,
|
|
id,
|
|
req, // Enforce access control
|
|
})
|
|
},
|
|
})
|
|
|
|
// 3. Create Tool
|
|
tools[`create_${slugKey}`] = tool({
|
|
description: `Create a new document in the ${collectionSlug} collection.`,
|
|
parameters: z.object({
|
|
data: z.record(z.any()).describe('A JSON object containing the data to insert.'),
|
|
}),
|
|
execute: async ({ data }) => {
|
|
return await payload.create({
|
|
collection: collectionSlug as any,
|
|
data,
|
|
req, // Enforce access control
|
|
})
|
|
},
|
|
})
|
|
|
|
// 4. Update Tool
|
|
tools[`update_${slugKey}`] = tool({
|
|
description: `Update an existing document in the ${collectionSlug} collection.`,
|
|
parameters: z.object({
|
|
id: z.union([z.string(), z.number()]).describe('The ID of the document to update.'),
|
|
data: z.record(z.any()).describe('A JSON object containing the fields to update.'),
|
|
}),
|
|
execute: async ({ id, data }) => {
|
|
return await payload.update({
|
|
collection: collectionSlug as any,
|
|
id,
|
|
data,
|
|
req, // Enforce access control
|
|
})
|
|
},
|
|
})
|
|
|
|
// 5. Delete Tool
|
|
tools[`delete_${slugKey}`] = tool({
|
|
description: `Delete a document from the ${collectionSlug} collection by ID.`,
|
|
parameters: z.object({
|
|
id: z.union([z.string(), z.number()]).describe('The ID of the document to delete.'),
|
|
}),
|
|
execute: async ({ id }) => {
|
|
return await payload.delete({
|
|
collection: collectionSlug as any,
|
|
id,
|
|
req, // Enforce access control
|
|
})
|
|
},
|
|
})
|
|
}
|
|
|
|
return tools
|
|
}
|