import BaseAgentService from '../BaseAgentService'; import { CONTENT_GENERATOR, CONTENT_GENERATOR_ACTIVE, CONTENT_GENERATOR_STATUS, CONTENT_GENERATOR_USAGE, CONTENT_GENERATOR_IMPROVE_PROMPT, CONTENT_GENERATOR_DETECT_COLUMNS, CONTENT_GENERATOR_PROMPT_TEMPLATES, CONTENT_CHECKER_EVALUATE, CONTENT_CHECKER_EVALUATE_BLOG, CONTENT_CHECKER_FIX, CONTENT_CHECKER_QUERY_LAB, contentGeneratorFromContentCheck, contentGeneratorInlineFromContentCheck, contentGeneratorBulkFromContentCheck, contentGeneratorPromptTemplate, } from './content-generator.routes'; import type { ContentGeneratorRequest, BaseAgentResponse, ContentGeneratorActiveJobResponse, ContentGeneratorJobResponse, ContentGeneratorStatusResponse, ContentGeneratorUsage, ImprovePromptResponse, DetectColumnsRequest, DetectColumnsApiResponse, InlineGenerateRequest, InlineGenerateResponse, ReplaceFromContentCheckRequest, BulkFromContentCheckRequest, PromptTemplateListApiResponse, PromptTemplateApiResponse, PromptTemplateDeleteApiResponse, PromptTemplateCreateRequest, PromptTemplateUpdateRequest, ContentCheckerEvaluateRequest, ContentCheckerEvaluateApiResponse, ContentCheckerFixRequest, ContentCheckerFixApiResponse, ContentCheckerBlogRequest, ContentCheckerBlogApiResponse, QueryLabRequest, QueryLabApiResponse, } from './content-generator.interface'; export const submitContentGenJob = async ( payload: ContentGeneratorRequest, clientId: string ): Promise> => { return await BaseAgentService.post( `${CONTENT_GENERATOR}?client_id=${encodeURIComponent(clientId)}`, payload ); }; /** * Enqueue a single-product content-gen job from a catalog-quality audit * row. Backend reads the per-row issues and feeds them to the model as * custom instructions. Caller navigates to `/content-generator` and the * page auto-restores the in-flight job for the merchant. * * @param {string} contentCheckJobId - Audit job that produced the row. * @param {string} sku - SKU of the product to fix. * @param {string} clientId - Recomaze client id. * @return {Promise>} Job response. */ export const submitContentGenFromContentCheck = async ( contentCheckJobId: string, sku: string, clientId: string, options?: ReplaceFromContentCheckRequest ): Promise> => { return await BaseAgentService.post( `${contentGeneratorFromContentCheck(contentCheckJobId, sku)}?client_id=${encodeURIComponent(clientId)}`, options ?? undefined ); }; /** * Generate copy for one audited product synchronously (gap / faq / custom / * rewrite). Returns ready-to-paste content inline: no email, no background job, * no credit debit. Backs the catalog-quality per-product Add-missing / FAQ * preview modals. * * @param {string} contentCheckJobId - Audit job that produced the row. * @param {string} sku - SKU of the product to generate for. * @param {InlineGenerateRequest} payload - Mode + optional prompts/language/temp. * @param {string} clientId - Recomaze client id. * @return {Promise>} Generated copy. */ export const inlineGenerateFromContentCheck = async ( contentCheckJobId: string, sku: string, payload: InlineGenerateRequest, clientId: string ): Promise> => { return await BaseAgentService.post( `${contentGeneratorInlineFromContentCheck(contentCheckJobId, sku)}?client_id=${encodeURIComponent(clientId)}`, payload ); }; /** * Enqueue one content-gen job across every product in an audit using the * merchant's chosen fields / prompts / tone. The resulting file is emailed. * * @param {string} contentCheckJobId - Audit job whose products to fix. * @param {BulkFromContentCheckRequest} payload - Field selection + tone config. * @param {string} clientId - Recomaze client id. * @return {Promise>} Job response. */ export const submitBulkFromContentCheck = async ( contentCheckJobId: string, payload: BulkFromContentCheckRequest, clientId: string ): Promise> => { return await BaseAgentService.post( `${contentGeneratorBulkFromContentCheck(contentCheckJobId)}?client_id=${encodeURIComponent(clientId)}`, payload ); }; export const getContentGenStatus = async ( jobId: string, clientId: string ): Promise> => { return await BaseAgentService.get( `${CONTENT_GENERATOR_STATUS}?job_id=${encodeURIComponent(jobId)}&client_id=${encodeURIComponent(clientId)}` ); }; /** * Fetch the in-flight content-generation job for the authenticated user. * * Backed by `GET /content-generator/active`. Returns * `{ active: false, status: null }` when nothing is running for this client * (the caller should clear any cached `job_id` from `localStorage`). */ export const getActiveContentGenJob = async ( clientId: string ): Promise> => { return await BaseAgentService.get( `${CONTENT_GENERATOR_ACTIVE}?client_id=${encodeURIComponent(clientId)}` ); }; export const getContentGenUsage = async ( plan: string, clientId: string ): Promise> => { return await BaseAgentService.get( `${CONTENT_GENERATOR_USAGE}?plan=${encodeURIComponent(plan)}&client_id=${encodeURIComponent(clientId)}` ); }; export const improvePrompt = async ( prompt: string, field: string, language: string, clientId: string ): Promise> => { return await BaseAgentService.post( `${CONTENT_GENERATOR_IMPROVE_PROMPT}?client_id=${encodeURIComponent(clientId)}`, { prompt, field, language } ); }; export const detectContentGenColumns = async ( payload: DetectColumnsRequest, clientId: string ): Promise => { return await BaseAgentService.post( `${CONTENT_GENERATOR_DETECT_COLUMNS}?client_id=${encodeURIComponent(clientId)}`, payload ); }; export const listPromptTemplates = async ( clientId: string, cursor?: string | null ): Promise => { const params = new URLSearchParams({ client_id: clientId }); if (cursor) params.set('cursor', cursor); return await BaseAgentService.get( `${CONTENT_GENERATOR_PROMPT_TEMPLATES}?${params.toString()}` ); }; export const createPromptTemplate = async ( payload: PromptTemplateCreateRequest, clientId: string ): Promise => { return await BaseAgentService.post( `${CONTENT_GENERATOR_PROMPT_TEMPLATES}?client_id=${encodeURIComponent(clientId)}`, payload ); }; export const updatePromptTemplate = async ( templateId: string, payload: PromptTemplateUpdateRequest, clientId: string ): Promise => { return await BaseAgentService.put( `${contentGeneratorPromptTemplate(templateId)}?client_id=${encodeURIComponent(clientId)}`, payload ); }; export const deletePromptTemplate = async ( templateId: string, clientId: string ): Promise => { return await BaseAgentService.delete( `${contentGeneratorPromptTemplate(templateId)}?client_id=${encodeURIComponent(clientId)}` ); }; /** * Score a pasted product title and/or description for AI search readiness. * The merchant is resolved from the JWT, so no client id is sent. * * @param {ContentCheckerEvaluateRequest} payload - Check type, copy, language. * @return {Promise} Scores plus pre-answered questions. */ export const evaluateProductContent = async ( payload: ContentCheckerEvaluateRequest ): Promise => { return await BaseAgentService.post(CONTENT_CHECKER_EVALUATE, payload); }; /** * Fix checker-flagged content through the full Product Content pipeline. * Synchronous: returns the complete generated row (title, description, SEO * fields, tags, FAQ). Billed at the inline fix-it rate (10 credits per topic). * * @param {ContentCheckerFixRequest} payload - Pasted content, evaluation issues, and knobs. * @return {Promise} Generated content row. */ export const fixProductContent = async ( payload: ContentCheckerFixRequest ): Promise => { return await BaseAgentService.post(CONTENT_CHECKER_FIX, payload); }; /** * Score a pasted blog post for AI SEO optimization. * * @param {ContentCheckerBlogRequest} payload - Blog content, target keywords, language. * @return {Promise} Blog evaluation result. */ export const evaluateBlogContent = async ( payload: ContentCheckerBlogRequest ): Promise => { return await BaseAgentService.post(CONTENT_CHECKER_EVALUATE_BLOG, payload); }; /** * Test whether a product description can answer a specific customer question. * * @param {QueryLabRequest} payload - Description, question, product type, language. * @return {Promise} Query lab result. */ export const evaluateQueryLab = async ( payload: QueryLabRequest ): Promise => { return await BaseAgentService.post(CONTENT_CHECKER_QUERY_LAB, payload); };