import { generateObject } from "ai";
import { z } from "zod";
import { PromptClassificationEnum } from "../types.js";
export class PromptInterpretTask {
    llmProvider;
    prompt;
    promptContext;
    appContextStore;
    abortController;
    result = null;
    constructor(llmProvider, prompt, promptContext, appContextStore) {
        this.llmProvider = llmProvider;
        this.prompt = prompt;
        this.promptContext = promptContext;
        this.appContextStore = appContextStore;
        this.abortController = new AbortController();
    }
    static defaultResult = {
        classification: "full_app_gen",
    };
    static mergeResults(_result1, result2) {
        result2 = result2 ?? PromptInterpretTask.defaultResult;
        return {
            classification: result2.classification,
        };
    }
    async isFullAppOrBroadUpdate() {
        const result = await this.resolve();
        return (result.classification === "broad_edit" ||
            result.classification === "full_app_gen" ||
            result.classification === "unknown");
    }
    buildSystemPrompt() {
        // NOTE(colin): question is not used yet
        const systemPrompt = `
You are an expert AI assistant for a low-code platform. Your task is to analyze a user's request and determine their primary intent.

Think step-by-step and analyze the user's request to determine the most fitting category from the Intent Definitions below.

# Intent Definitions
- **full_app_gen**: The user wants to create a new application from scratch. The prompt will describe the app's purpose. Examples: "build a user management dashboard", "create an app to track inventory".
- **broad_edit**: The user wants to add a new feature or make a significant change to the existing application. This often involves creating new components, deleting components, changing the hierarchy of components, multi-component layout, or any API change. Examples: "add a form to create new users", "create a detail view for the selected table row", "change the container to a modal", "move the table to the right side".
- **specific_edit**: The user wants to make small, targeted changes to existing component properties. Examples: "make the button blue", "change the table title".
- **unknown**: The user's intent is unclear, irrelevant, or gibberish.

# User Request
Analyze the following user request and determine the user's primary intent.

**User Request:** "${this.prompt}"

Classify this request based on the intent definitions above.`;
        const schema = z.object({
            classification: PromptClassificationEnum.describe("The user's primary intent. Analyze the prompt to determine the most fitting category."),
        });
        return { systemPrompt, schema };
    }
    abort() {
        this.abortController.abort();
    }
    isAborted() {
        return this.abortController.signal.aborted;
    }
    resolve() {
        if (this.result) {
            return this.result;
        }
        this.result = this.doResolve();
        return this.result;
    }
    async doResolve() {
        if (this.appContextStore.isEssentiallyBlank()) {
            return {
                classification: "full_app_gen",
            };
        }
        const { systemPrompt, schema } = this.buildSystemPrompt();
        const { object: interpretation } = await generateObject({
            model: this.llmProvider.modelForTask("classifyPrompt"),
            schema,
            prompt: systemPrompt,
            abortSignal: this.abortController.signal,
        });
        const classification = interpretation
            .classification;
        if (classification === "specific_edit") {
            const hasApis = this.promptContext.entities.some((entity) => entity.type === "api" || entity.type === "integration");
            const hasCustomComponents = this.promptContext.entities.some((entity) => this.appContextStore.componentSemanticsById[entity.id]
                ?.isCustomComponent ?? false);
            // NOTE(colin): we avoid specific edits for certain components at the moment
            const complexComponents = ["Table", "Modal", "Slideout"];
            const hasOtherComplexComponents = this.promptContext.entities.some((entity) => complexComponents.includes(this.appContextStore.componentSemanticsById[entity.id]
                ?.tagName ?? ""));
            if (hasApis || hasCustomComponents || hasOtherComplexComponents) {
                return {
                    classification: "broad_edit",
                };
            }
        }
        return {
            classification,
        };
    }
}
//# sourceMappingURL=prompt-interpret-task.js.map