import { z } from 'zod';
import { defineTool, } from '../toolDefinition.js';
import { AgentToolNames } from '../shared/agentToolNames.js';
/**
 * GetTestDefinitionDefinition - Tool definition for fetching test entity and its flow definitions.
 */
export const getTestDefinitionParamsSchema = z.object({
    test_run_id: z.string().optional().meta({
        description: 'Test run ID to fetch the test definition for. Either test_run_id or test_id must be provided.',
    }),
    test_id: z.string().optional().meta({
        description: 'Test ID (journey ID) to fetch the test definition for directly, without requiring a test run. Either test_run_id or test_id must be provided. Use this when you have a test ID but no test run (e.g., newly authored tests that have not been run yet).',
    }),
    include_nested_flows: z.boolean().optional().meta({
        description: 'Whether to recursively fetch nested flow definitions. Default: true',
    }),
    max_flow_depth: z.number().optional().meta({
        description: 'Maximum depth for nested flow resolution. Default: 3. Maximum: 5.',
    }),
});
const flowStepInfoSchema = z.lazy(() => z.object({
    stepIndex: z.number().meta({ description: 'Index of the step within the flow' }),
    stepNumber: z.string().optional().meta({
        description: 'Human-readable step number with dotted notation (e.g., "1", "2.1", "2.1.3" for nested steps in step groups or embedded flows)',
    }),
    description: z.string().meta({ description: 'Description of what the step does' }),
    isNestedFlow: z.boolean().optional().meta({ description: 'Whether this step executes a nested flow' }),
    nestedFlowId: z.string().optional().meta({ description: 'ID of the nested flow if this step executes one' }),
    isStepGroup: z
        .boolean()
        .optional()
        .meta({ description: 'Whether this step is a step group containing nested steps' }),
    nestedSteps: z
        .array(z.lazy(() => flowStepInfoSchema))
        .optional()
        .meta({ description: 'Nested steps within a step group (for step groups only)' }),
    isJavascriptStep: z.boolean().optional().meta({ description: 'Whether this step executes JavaScript code' }),
    javascriptCode: z
        .string()
        .optional()
        .meta({ description: 'The JavaScript code executed by this step (for inline JS steps)' }),
    snippetId: z.string().optional().meta({
        description: 'Invariant ID of the snippet referenced by this step (matches invariant_id in flow snippets array)',
    }),
    note: z.string().optional().meta({ description: 'User-provided note/documentation for this step' }),
    autoGeneratedDescription: z
        .string()
        .optional()
        .meta({ description: 'AI-generated description of what this step does' }),
    descriptionSource: z
        .enum(['user', 'ai', 'default'])
        .optional()
        .meta({ description: 'Source of the step description: user-provided, AI-generated, or default' }),
    featureIds: z
        .array(z.string())
        .optional()
        .meta({ description: 'IDs of advanced features used by this step (e.g., ai_assertion, visual_change)' }),
}));
const snippetInfoSchema = z.object({
    invariant_id: z.string().meta({ description: 'Snippet invariant ID' }),
    name: z.string().optional().meta({ description: 'Snippet name' }),
    description: z.string().optional().meta({ description: 'Snippet description' }),
    snippet_type: z.string().optional().meta({ description: 'Type of snippet (e.g., javascript)' }),
    body: z.string().optional().meta({
        description: 'The decoded body/code of the snippet. Omitted when body_truncated is true — call get_snippet_details with invariant_id to fetch the full body.',
    }),
    body_truncated: z.boolean().optional().meta({
        description: 'True when the snippet body was stripped because it exceeded the inline size limit. Fetch the full body via get_snippet_details if you need it for diagnosis.',
    }),
    body_length: z.number().optional().meta({
        description: 'The character length of the original body. Only set when body_truncated is true.',
    }),
    parameters: z
        .array(z.object({
        name: z.string(),
        default_value: z.string().optional(),
    }))
        .optional()
        .meta({ description: 'Parameters that the snippet accepts' }),
});
const flowDefinitionSchema = z.object({
    flowId: z.string().meta({ description: 'Flow invariant ID' }),
    description: z.string().optional().meta({ description: 'Flow description' }),
    isReusable: z
        .boolean()
        .optional()
        .meta({ description: 'Whether this flow is a reusable flow that can be called from other tests' }),
    steps: z.array(flowStepInfoSchema).meta({ description: 'Steps in this flow' }),
    parameters: z
        .array(z.object({
        name: z.string(),
        defaultValue: z.string().optional(),
    }))
        .optional()
        .meta({ description: 'Parameters that can be passed to this flow' }),
    nestedFlowIds: z.array(z.string()).optional().meta({ description: 'IDs of flows referenced by this flow' }),
    snippets: z
        .array(snippetInfoSchema)
        .optional()
        .meta({ description: 'JavaScript/code snippets referenced by steps in this flow' }),
});
const labelSchema = z.object({
    name: z.string().meta({ description: 'Label name' }),
    color: z.string().optional().meta({ description: 'Label color' }),
});
const tagSchema = z.object({
    name: z.string().meta({ description: 'Tag name' }),
    value: z.string().optional().meta({ description: 'Tag value' }),
});
const testDefinitionSchema = z.object({
    testId: z.string().meta({ description: 'Test ID' }),
    testInvariantId: z.string().optional().meta({ description: 'Test invariant ID' }),
    name: z.string().meta({ description: 'Test name' }),
    description: z.string().optional().meta({ description: 'Test description' }),
    intent: z.string().optional().meta({ description: 'Test intent - what the test is meant to verify' }),
    testType: z.string().optional().meta({ description: 'Type of test (browser, api, mobile)' }),
    applicationId: z.string().optional().meta({ description: 'Application this test belongs to' }),
    credentialsId: z.string().optional().meta({ description: 'ID of the credentials used by this test' }),
    url: z.string().optional().meta({ description: 'The URL used when creating this test version' }),
    labels: z.array(labelSchema).optional().meta({ description: 'User-provided labels for test organization' }),
    tags: z.array(tagSchema).optional().meta({ description: 'Tags associated with this test' }),
    flows: z.array(flowDefinitionSchema).meta({ description: 'Flows that make up this test, in execution order' }),
    totalStepsAcrossFlows: z.number().meta({ description: 'Total number of steps across all flows' }),
});
export const getTestDefinitionResponseSchema = z.object({
    test: testDefinitionSchema.meta({ description: 'Test definition with all flow details' }),
    nestedFlows: z
        .array(flowDefinitionSchema)
        .optional()
        .meta({ description: 'Additional nested flows referenced by the main flows' }),
    formattedStepList: z.string().optional().meta({
        description: 'Pre-formatted step list with each step on its own line and proper indentation for nested flows. Use this for display to users.',
    }),
    note: z.string().optional().meta({ description: 'Any notes about the response' }),
});
export const GetTestDefinitionToolDefinition = defineTool({
    name: AgentToolNames.GetTestDefinition,
    description: `Retrieves the test definition including all flows, steps, and code snippets.
Accepts either a test_run_id or a test_id (journey ID). Use test_id when you have a test ID
but no test run (e.g., newly authored tests that have not been run yet).

Use this tool to understand:
- What the test is designed to verify (test intent and description)
- The test's configuration: credentials, target URL, application
- The sequence of flows that make up the test
- What each step in each flow does
- How flows are nested within other flows
- Parameters that flows accept
- JavaScript code executed by steps (inline JS and snippets)
- Code snippets referenced in the test and their source code

This provides the "expected behavior" of the test, which you can compare against
actual execution results from get_test_run_info to understand failures.`,
    argumentsSchema: getTestDefinitionParamsSchema,
    responseSchema: getTestDefinitionResponseSchema,
});
//# sourceMappingURL=GetTestDefinitionDefinition.js.map