import { z } from "zod";
import { getPrefixedLogger } from "../../../../util/logger.js";
import { createToolFactory, ToolCategory } from "../../tools2/types.js";
import { buildApiArtifact } from "./build-api-artifact.js";
export { extractIntegrationIdsFromSource } from "./analysis.js";
export const buildApiToolFactory = createToolFactory("buildApi", ({ clark, services, scopeUpdateQueue, }) => {
    return {
        category: ToolCategory.API,
        description: `
Compile, validate, and save the API. This tool performs the following steps:
1. Reads the API source from file
2. Compiles to Superblocks API YAML and validates syntax
3. Performs static analysis to catch common mistakes
4. Validates proto compatibility

IMPORTANT: Before using ANY integration, you MUST call grepMetadata to explore its metadata:

**Database integrations**: Get table/column names and types. Do NOT make up column names.

**OpenAPI integrations** (REST APIs, AI providers like Gemini/OpenAI/Anthropic):
- Search for available endpoints: \`\\.paths\\[.*\\]\`
- Search for parameter values: \`\\.info\\.description\` (often contains setup info, available models)
- Search for examples: \`\\.example\` (shows valid parameter values)
- Do NOT assume parameter values from training data - always verify against the spec
`,
        inputSchema: z.object({
            apiName: z.string().describe("The name of the API"),
        }),
        execute: async ({ apiName }) => {
            const logger = getPrefixedLogger(`[buildApi-${apiName}]`);
            try {
                const { isNewApi, inputInterface, responseType } = await buildApiArtifact({
                    apiName,
                    services,
                    scopeUpdateQueue,
                    logger,
                });
                // Build succeeded - clear any previous failure for this API
                clark.context.failedApiBuilds?.delete(apiName);
                let message = `API ${apiName} has been successfully compiled, validated, and saved.`;
                message += `\n\nGenerated TypeScript types:`;
                message += `\n${inputInterface}`;
                message += `\n${responseType}`;
                message += `\n\nTypes saved to apis/${apiName}.d.ts`;
                message += `\n\nThe API is now available in the application. You MUST call testApi to execute and verify the API behavior before moving on to other work`;
                // Mark API as needing testing - rebuild resets test status.
                // Also clear denied: a rebuild produces new code, so a previous
                // denial of the old version shouldn't suppress testing the new one.
                clark.context.apiTestingState ??= {
                    untested: new Set(),
                    failed: new Set(),
                    passed: new Set(),
                    denied: new Set(),
                };
                clark.context.apiTestingState.untested.add(apiName);
                clark.context.apiTestingState.failed.delete(apiName);
                clark.context.apiTestingState.passed.delete(apiName);
                clark.context.apiTestingState.denied.delete(apiName);
                return {
                    message,
                    apiName,
                    isNewApi,
                };
            }
            catch (error) {
                // Track the failed build so finalize will be blocked
                clark.context.failedApiBuilds ??= new Set();
                clark.context.failedApiBuilds.add(apiName);
                throw error;
            }
        },
        getSummary: (_input, output) => {
            const status = output.isNewApi ? "Created" : "Updated";
            return {
                output: `${status} successfully`,
            };
        },
    };
});
//# sourceMappingURL=build-api.js.map