import type { UiAction } from '@servicenow/sdk-core/ui';
import type { TableName, Record as DbRecord } from '@servicenow/sdk-core/db';
import type { Role } from '@servicenow/sdk-core/app';
import type { ScriptInclude } from '@servicenow/sdk-core/sys';
import type { Subflow } from '@servicenow/sdk-core/flow';
/** Subflow definition return type stub */
type SubflowRef = ReturnType<typeof Subflow<any, any, any>>;
/** Action definition return type stub */
type ActionRef = any;
/**
 * ==========================================
 * TOOL SUPPORT TYPE DEFINITIONS
 * ==========================================
 */
/**
 * Brand symbol for tool output references
 * Used to distinguish tool outputs from regular strings at compile time
 * @internal
 */
declare const __toolOutputBrand: unique symbol;
/**
 * Brand symbol for tool name storage
 * Uses a symbol key so it does not appear in IntelliSense autocomplete.
 * @internal
 */
declare const __toolName: unique symbol;
/**
 * Brand symbol for storing TOutputs tuple on ToolHandle
 * Allows PromptBuilder to extract output field names via inference.
 * @internal
 */
declare const __toolOutputs: unique symbol;
/**
 * Brand symbol for skill input references
 * Used to distinguish skill inputs from regular strings at compile time
 * @internal
 */
declare const __skillInputBrand: unique symbol;
/**
 * Represents a reference to a tool's output
 * Used for type-safe tool chaining and dependency management
 */
export interface ToolOutputRef {
    readonly [__toolOutputBrand]: true;
}
/**
 * Represents a reference to a skill input field
 * Used for type-safe Decision condition field references
 * Branded intersection allows use as string in tool inputs while restricting Decision.field
 */
export type SkillInputRef<K extends string = string> = K & {
    readonly [__skillInputBrand]: true;
};
export type ScriptTypeToolInput = {
    type: 'script';
    /** Inline function or Now.include() file reference */
    script: ((currentInputs: unknown, context: unknown) => unknown) | string;
};
/**
 * Conditional execution configuration for tools
 * Determines if a tool should run based on runtime conditions
 *
 * @example
 * ```typescript
 * // No condition (always runs) - DEFAULT
 * condition: { type: 'none' }
 *
 * // String literal script - runs when condition returns true
 * condition: {
 *   type: 'script',
 *   script: `(currentInputs, context) => {
 *     return context.getValue('PreviousTool.status') === 'success';
 *   }`
 * }
 *
 * // External file via Now.include()
 * condition: { type: 'script', script: Now.include('./scripts/condition.js') }
 * ```
 */
export type ToolCondition = {
    type: 'none';
} | {
    type: 'script';
    script: string;
};
/**
 * Union type for all possible tool input values
 * - string: Static string value or template string like "{{input.fieldName}}"
 * - ScriptTypeToolInput: Dynamic script-based input
 * - ToolOutputRef: Reference to another tool's output
 */
export type ToolInputValue = string | ScriptTypeToolInput | ToolOutputRef;
/**
 * User access configuration for NowAssist Skills
 * Defines who can access and execute the skill
 *
 * @example
 * ```typescript
 * // For any authenticated user (most common)
 * const publicAccess: UserAccessConfig = {
 *   $id: Now.ID['my_skill_public_acl'],
 *   type: 'authenticated'
 * }
 *
 * // For specific roles using sys_ids (strings)
 * const roleBasedAccess: UserAccessConfig = {
 *   $id: Now.ID['my_skill_role_acl'],
 *   type: 'roles',
 *   roles: [
 *     '2831a114c611228501d4ea6c309d626d', // admin role sys_id
 *     'b85d44954a3623120004689b2d5dd60a'  // itil role sys_id
 *   ]
 * }
 *
 * // Using Role objects (for new custom roles)
 * // Note: Requires import { Role } from '@servicenow/sdk/core'
 * const roleObjectAccess: UserAccessConfig = {
 *   $id: Now.ID['my_skill_custom_role_acl'],
 *   type: 'roles',
 *   roles: [
 *     Role({
 *       name: 'x_your_app.skill_user', // Use your app prefix
 *       description: 'Can use custom skills'
 *     }),
 *     Role({
 *       name: 'x_your_app.skill_admin',
 *       description: 'Can manage custom skills'
 *     })
 *   ]
 * }
 *
 * // Using sys_user_role records (for existing roles)
 * const recordBasedAccess: UserAccessConfig = {
 *   $id: Now.ID['my_skill_record_acl'],
 *   type: 'roles',
 *   roles: [
 *     { sys_user_role: 'admin' },
 *     { sys_user_role: 'itil' }
 *   ]
 * }
 *
 * // Mixed approach (all types together)
 * const mixedAccess: UserAccessConfig = {
 *   $id: Now.ID['my_skill_mixed_acl'],
 *   type: 'roles',
 *   roles: [
 *     '2831a114c611228501d4ea6c309d626d', // sys_id string
 *     Role({ name: 'x_your_app.custom_role' }), // Role object
 *     { sys_user_role: 'admin' } // Record reference
 *   ]
 * }
 *
 * // Usage in NowAssistSkillConfig:
 * // securityControls: {
 * //   userAccess: publicAccess, // or any of the above
 * //   roleRestrictions: ['2831a114c611228501d4ea6c309d626d'] // admin role sys_id (ONLY sys_ids)
 * // }
 * ```
 */
export type UserAccessConfig = Now.Internal.WithID<{
    /** For any authenticated user */
    type: 'authenticated';
    /** Array of role sys_ids, Role objects, or sys_user_role records */
    roles?: (string | Role | DbRecord<'sys_user_role'>)[];
}> | Now.Internal.WithID<{
    /** For specific roles only */
    type: 'roles';
    /** Array of role sys_ids, Role objects, or sys_user_role records */
    roles: (string | Role | DbRecord<'sys_user_role'>)[];
}>;
/**
 * Helper type for string unions that preserves autocomplete.
 * Suggests known values in IntelliSense but accepts any string.
 * @internal
 */
type StringWithSuggestions<T> = T | ((string | number) & Record<never, never>);
/**
 * Helper type to normalize input names to platform format.
 * Converts spaces to underscores and lowercases the string.
 * Used for filterCondition keys to support dot-notation paths.
 * @example 'User table' → 'user_table'
 * @internal
 */
type ToNormalized<S extends string> = S extends `${infer A} ${infer B}` ? `${Lowercase<A>}_${ToNormalized<B>}` : Lowercase<S>;
/**
 * Decision condition types for branching logic
 * Supports field-based conditions and scripts
 *
 * Field accepts:
 * - String literal: 'inputName.field' for nested field access (e.g., 'glide_record_input.active')
 * - Skill input reference: t.input.fieldName (returns SkillInputRef)
 * - Tool output reference: tool.output (returns ToolOutputRef)
 */
export type DecisionCondition = {
    /**
     * Field to evaluate — can be:
     * - String literal: 'inputName.field' for nested field access
     * - Skill input reference: t.input.fieldName (returns SkillInputRef)
     * - Tool output reference: tool.output (returns ToolOutputRef)
     */
    field: string | SkillInputRef | ToolOutputRef;
    operator: 'is' | 'is not';
    value: string;
} | {
    script: string;
};
/**
 * Decision branch configuration
 * Defines a conditional path to a target tool
 * Generic over TTargets for type-safe target references
 */
export interface DecisionBranch<TTargets extends string = string> {
    /** Branch name for identification */
    name: string;
    /**
     * Target tool to route to when condition matches
     * Type-safe: only allows values from the Decision's targets array
     */
    to: TTargets;
    /** Condition that determines if this branch is taken */
    condition: DecisionCondition;
}
/**
 * Represents a handle to a tool with typed outputs.
 *
 * Output fields are placed at the TOP LEVEL of the handle, matching the
 * platform's template syntax where outputs are accessed directly:
 *   - Single-output tools:  tool.output          → {{toolName.output}}
 *   - Multi-output tools:   tool.fieldName       → {{toolName.fieldName}}
 *   - Dynamic-output tools: tool.anyField        → {{toolName.anyField}}
 *
 * All tool types use the same mapped type — no conditional branching:
 *   - `readonly ['output']`                    → { output: ToolOutputRef }
 *   - `readonly ['provider', 'response', ...]` → { provider: ToolOutputRef, response: ToolOutputRef, ... }
 *   - `readonly string[]` (dynamic)            → { [key: string]: ToolOutputRef }
 */
export type ToolHandle<TName extends string, TOutputs extends readonly string[]> = {
    /** @internal Tool name — hidden from IntelliSense */
    readonly [__toolName]: TName;
    /** @internal Output field names — used by PromptBuilder for type inference */
    readonly [__toolOutputs]: TOutputs;
} & {
    readonly [K in TOutputs[number]]: ToolOutputRef;
};
/**
 * Base type that all ToolHandle variants are assignable to.
 * Used as a generic constraint in `ToolDependency`, `Decision.depends`, etc.
 *
 * This is a structural base type that only requires the internal symbol keys.
 * All concrete ToolHandle types satisfy this because they all have
 * `[__toolName]` and `[__toolOutputs]` — the mapped output fields are extra
 * properties that structural subtyping accepts.
 *
 * @internal
 */
export type BaseToolHandle = {
    readonly [__toolName]: string;
    readonly [__toolOutputs]: readonly string[];
};
/**
 * ==========================================
 * NOW ASSIST NAMESPACE - TOOL GRAPH BUILDER
 * ==========================================
 */
/**
 * NowAssistTools namespace containing tool graph builder and related utilities
 * Provides type-safe tool chaining and dependency management
 * @internal - Users should use the NowAssist API object instead
 */
export declare namespace NowAssistTools {
    /**
     * Minimal dependency reference for tool chaining
     * Only requires the tool name for dependency tracking
     */
    type ToolDependency = Pick<BaseToolHandle, typeof __toolName>;
    /**
     * Valid data types for FlowAction, Subflow, and Predictive Intelligence tool inputs/outputs.
     * These are the OneExtend-compatible types after conversion from Flow Designer types.
     *
     * Common OneExtend types:
     * - 'string' - Default string type
     * - 'boolean' - Boolean values
     * - 'numeric' - integer, float, decimal, longint
     * - 'json_object' - json, object
     * - 'json_array' - array.object
     * - 'simple_array' - array.boolean, array.datetime, array.integer, array.string
     * - 'glide_record' - reference type
     * - 'table' - Table name type
     *
     * Flow Designer types (passed through as-is):
     * - 'choice' - Choice/dropdown field
     * - 'date' - Date field
     * - 'datetime' - Date/time field
     * - 'duration' - Duration field
     * - 'html' - HTML content
     * - 'conditions' - Condition builder
     * - 'script' - Script field
     *
     * Invalid types that are NOT supported: 'Document ID', 'Reference', 'Snapshot Template Value'
     */
    export type ToolDataType = 'string' | 'boolean' | 'numeric' | 'json_object' | 'json_array' | 'simple_array' | 'glide_record' | 'table' | 'object' | 'choice' | 'date' | 'datetime' | 'duration' | 'html' | 'conditions' | 'script' | (string & {});
    /**
     * Input for Script tool - name and value (type is always 'string')
     */
    export interface ScriptToolInput {
        /** Unique identifier for the attribute mapping record - required for stable identity */
        $id: Now.Internal.ExplicitKey;
        /** Matches the input parameter name defined on the Script Include */
        name: string;
        /** Input value - can be static string, template string ({{...}}), or tool output reference */
        value: ToolInputValue;
    }
    /**
     * Input for Subflow tool - name, type, and value (dynamic per subflow)
     */
    export interface SubflowToolInput {
        /** Unique identifier for the attribute mapping record - required for stable identity */
        $id: Now.Internal.ExplicitKey;
        /** Matches the input parameter name defined on the Subflow */
        name: string;
        /**
         * Input type - must be a valid ToolDataType.
         * Invalid types ('Document ID', 'Reference', 'Snapshot Template Value') are not supported.
         * @default 'string'
         */
        type?: ToolDataType;
        /** Input value - can be static string, template string ({{...}}), or tool output reference */
        value: ToolInputValue;
    }
    /**
     * Input for Skill tool - definitionAttributeId and value (type is always 'string')
     */
    export interface SkillToolInput {
        /**
         * sys_id of the target skill's input definition attribute (sys_one_extend_definition_attribute).
         * Accepts a raw sys_id string or a DbRecord reference.
         *
         * @example
         * // Using raw sys_id
         * definitionAttributeId: 'abc123def456...'
         *
         * // Using DbRecord reference
         * definitionAttributeId: Now.Record('sys_one_extend_definition_attribute', 'abc123...')
         */
        definitionAttributeId: string | DbRecord<'sys_one_extend_definition_attribute'>;
        /** Input value - can be static string, template string ({{...}}), or tool output reference */
        value: ToolInputValue;
    }
    /**
     * Output attribute mapping for a single Skill-as-Tool output.
     * Maps to a sys_one_extend_definition_attribute record on the target skill.
     */
    export interface SkillToolOutputAttribute {
        /**
         * sys_id of the target skill's output definition attribute (sys_one_extend_definition_attribute).
         * Accepts a raw sys_id string or a DbRecord reference.
         *
         * @example
         * // Using raw sys_id
         * definitionAttributeId: 'abc123def456...'
         *
         * // Using DbRecord reference
         * definitionAttributeId: Now.Record('sys_one_extend_definition_attribute', 'abc123...')
         */
        definitionAttributeId: string | DbRecord<'sys_one_extend_definition_attribute'>;
        /**
         * Whether to truncate this output to prevent exceeding token limits
         * @default false
         */
        truncate?: boolean;
    }
    /**
     * Output mapping for Skill-as-Tool outputs.
     * The 5 standard outputs (provider, response, error, errorcode, status) are mandatory.
     * Additional custom outputs can be added as extra keys.
     *
     * @example
     * outputs: {
     *     provider:  { definitionAttributeId: 'abc123...' },
     *     response:  { definitionAttributeId: 'def456...', truncate: true },
     *     error:     { definitionAttributeId: 'ghi789...' },
     *     errorcode: { definitionAttributeId: 'jkl012...' },
     *     status:    { definitionAttributeId: 'mno345...' },
     *     // custom outputs (optional)
     *     myCustom:  { definitionAttributeId: 'pqr678...' },
     * }
     */
    export type SkillToolOutputs = {
        /** Provider attribute (mandatory) */
        provider: SkillToolOutputAttribute;
        /** Response attribute (mandatory) */
        response: SkillToolOutputAttribute;
        /** Error attribute (mandatory) */
        error: SkillToolOutputAttribute;
        /** Error code attribute (mandatory) */
        errorcode: SkillToolOutputAttribute;
        /** Status attribute (mandatory) */
        status: SkillToolOutputAttribute;
    } & {
        /** Additional custom output attributes */
        [customOutput: string]: SkillToolOutputAttribute;
    };
    /**
     * Input for FlowAction tool - name, type, and value (dynamic per action)
     */
    export interface FlowActionToolInput {
        /** Unique identifier for the attribute mapping record - required for stable identity */
        $id: Now.Internal.ExplicitKey;
        /** Matches the input parameter name defined on the Flow Action */
        name: string;
        /**
         * Input type - must be a valid ToolDataType.
         * Invalid types ('Document ID', 'Reference', 'Snapshot Template Value') are not supported.
         */
        type: ToolDataType;
        /** Input value - can be static string, template string ({{...}}), or tool output reference */
        value: ToolInputValue;
    }
    /**
     * Output for FlowAction tool - name, type, and truncate (dynamic per action)
     */
    export interface FlowActionToolOutput {
        /** Unique identifier for the attribute mapping record - required for stable identity */
        $id: Now.Internal.ExplicitKey;
        /** Matches the output parameter name defined on the Flow Action */
        name: string;
        /**
         * Output type - must be a valid ToolDataType.
         * Invalid types ('Document ID', 'Reference', 'Snapshot Template Value') are not supported.
         */
        type: ToolDataType;
        /**
         * Whether to truncate the output to prevent exceeding token limits
         * @default false
         */
        truncate?: boolean;
    }
    /**
     * Output for Subflow tool - name, type, and truncate (dynamic per subflow)
     */
    export interface SubflowToolOutput {
        /** Unique identifier for the attribute mapping record - required for stable identity */
        $id: Now.Internal.ExplicitKey;
        /** Matches the output parameter name defined on the Subflow */
        name: string;
        /**
         * Output type - must be a valid ToolDataType.
         * Invalid types ('Document ID', 'Reference', 'Snapshot Template Value') are not supported.
         * @default 'object'
         */
        type?: ToolDataType;
        /**
         * Whether to truncate the output to prevent exceeding token limits
         * @default false
         */
        truncate?: boolean;
    }
    /**
     * Output definition for a Script tool.
     * Script tools have a single standard output (name='output', type='string').
     *
     * Optional — if omitted, the output is auto-generated with a derived `$id`
     *
     * @example
     * // Minimal — defaults: name='output', type='string'
     * output: { $id: Now.ID['my_script_tool_output'] }
     *
     */
    export type ScriptToolOutput = Now.Internal.WithID<{
        /**
         * Output name
         */
        name?: string;
        /**
         * Output type
         */
        type?: string;
    }>;
    /**
     * Per-output truncate configuration for tools with fixed outputs (WebSearch, Skill)
     * Allows fine-grained control over which outputs should be truncated
     */
    export interface FixedOutputTruncateConfig {
        /** Truncate provider output @default false */
        provider?: boolean;
        /** Truncate response output @default false */
        response?: boolean;
        /** Truncate error output @default false */
        error?: boolean;
        /** Truncate errorCode output @default false */
        errorcode?: boolean;
        /** Truncate status output @default false */
        status?: boolean;
    }
    /**
     * WebSearch AI Answers config - uses AI providers (Perplexity, OpenAI, Gemini, Azure OpenAI)
     */
    export interface WebSearchAiAnswersConfig {
        /** Search result type - AI Answers */
        searchType: 'ai_answers';
        /**
         * AI search provider for generating responses
         * If not provided, platform uses its default provider
         */
        aiSearchProviders?: '' | 'perplexity' | 'openai' | 'gemini' | 'azure_openAI';
        /** Search query - template string ({{...}}) or static string */
        query: ToolInputValue;
    }
    /**
     * WebSearch Scraping config - uses Now LLM with scraping API
     */
    export interface WebSearchScrapingConfig {
        /** Search result type - Searching and Scraping */
        searchType: 'searching_and_scraping';
        /** Search query - template string ({{...}}) or static string */
        query: ToolInputValue;
        /** Sites or domains to search within (e.g., "support.microsoft.com") */
        sites?: ToolInputValue;
        /**
         * Number of search results to get in response
         * @default 3
         */
        numResults?: number;
        /** Country where the results will come from */
        country?: string;
        /**
         * Maximum number of tokens to include in response
         * @default 1000
         */
        maxTokens?: number;
    }
    /**
     * Tool graph builder interface providing type-safe tool creation methods
     * Generic over skill inputs to enable input field autocomplete
     */
    export interface ToolGraphBuilder<TSkillInputs extends readonly InputAttribute[]> {
        /**
         * Proxy object providing access to skill input fields
         * Returns template strings like "{{input.fieldName}}"
         * Type returns SkillInputRef<K> which is:
         * - Assignable to string (for tool inputs and prompts)
         * - Accepted by DecisionCondition.field (branded type)
         */
        readonly input: {
            readonly [K in TSkillInputs[number]['name']]: SkillInputRef<K>;
        };
        /**
         * Create a Script tool (Script Include / External Script)
         * Note: Input type is always 'string', single output accessed via `tool.output`
         * Platform reference: `{{toolName.output}}`
         * @param name - Unique tool name
         * @param config - Tool configuration with scriptId, inputs, and dependencies
         */
        Script<TName extends string>(name: TName, config: Now.Internal.WithID<{
            /**
             * Unique identifier for the tool's capability record
             * Required to ensure stable identity across name changes
             * @example Now.ID['my_skill_script_tool']
             */
            $capabilityId: Now.Internal.ExplicitKey;
            /**
             * Reference to the Script Include.
             * Accepts:
             * - A raw sys_id string
             * - A ScriptInclude return value for same-project references (RECOMMENDED)
             * - DbRecord<'sys_script_include'> for explicit record reference
             *
             * @example
             * // Using ScriptInclude variable (same project - RECOMMENDED)
             * const MyHelper = ScriptInclude({ $id: Now.ID['my_helper'], ... })
             * scriptId: MyHelper
             *
             * // Using raw sys_id (external script)
             * scriptId: 'abc123def456...'
             *
             * // Using DbRecord reference
             * scriptId: Now.Record('sys_script_include', 'abc123...')
             */
            scriptId: string | ReturnType<typeof ScriptInclude> | DbRecord<'sys_script_include'>;
            scriptFunctionName?: string;
            depends?: ToolDependency[];
            /**
             * Input mappings - array of { name, value } objects
             * Note: Input type is always 'string' for Script tools
             */
            inputs?: ScriptToolInput[];
            /**
             * Script tools have a single standard output (name='output', type='string').
             * Optional — if omitted, auto-generated with a derived `$id` and defaults.
             *
             * @example
             * output: { $id: Now.ID['my_script_tool_output'] }
             */
            output?: NowAssistTools.ScriptToolOutput;
            /**
             * Whether to truncate the output to prevent exceeding token limits
             * @default false
             */
            truncate?: boolean;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, readonly ['output']>;
        /**
         * Create an InlineScript tool
         * Note: InlineScript has NO inputs, single output accessed via `tool.output`
         * Platform reference: `{{toolName.output}}`
         * @param name - Unique tool name
         * @param config - Tool configuration with script and dependencies
         */
        InlineScript<TName extends string>(name: TName, config: Now.Internal.WithID<{
            /**
             * Script content as a string literal or Now.include() reference.
             * Arrow functions are NOT supported - use string literals instead.
             * @example script: `(context) => { return context.getValue('field'); }`
             * @example script: Now.include('./scripts/inline.js')
             */
            script: string;
            depends?: ToolDependency[];
            /**
             * Whether to truncate the output to prevent exceeding token limits
             * @default false
             */
            truncate?: boolean;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, readonly ['output']>;
        /**
         * Create a Flow Action tool
         * Note: Inputs and outputs are DYNAMIC - they vary per flow action
         * @param name - Unique tool name
         * @param config - Tool configuration with actionId, inputs, outputs, and dependencies
         */
        FlowAction<TName extends string, TOutputNames extends readonly string[] = readonly string[]>(name: TName, config: Now.Internal.WithID<{
            /**
             * Unique identifier for the tool's capability record
             * Required to ensure stable identity across name changes
             * @example Now.ID['my_skill_flow_action_tool']
             */
            $capabilityId: Now.Internal.ExplicitKey;
            /**
             * Reference to the action to call.
             * Accepts:
             * - An Action definition (same project - RECOMMENDED for type safety)
             * - A Now.ID reference for same-project actions
             * - A raw sys_id string (fallback for external actions)
             *
             * @example
             * // Using Action definition (same project - RECOMMENDED)
             * import { myAction } from './actions/my-action.now'
             * actionId: myAction
             *
             * // Using Now.ID reference (same project)
             * actionId: Now.ID['my_action']
             *
             * // Using raw sys_id (external action)
             * actionId: 'abc123def456...'
             */
            actionId: string | ActionRef;
            depends?: ToolDependency[];
            /**
             * Input mappings - array of { name, type, value } objects
             * Note: Inputs are DYNAMIC - they vary per flow action
             */
            inputs?: FlowActionToolInput[];
            /**
             * Output definitions - array of { name, type, truncate? } objects
             * Note: Outputs are DYNAMIC - they vary per flow action
             */
            outputs?: FlowActionToolOutput[];
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, TOutputNames>;
        /**
         * Create a Subflow tool
         * Note: Inputs and outputs are DYNAMIC - they vary per subflow
         * @param name - Unique tool name
         * @param config - Tool configuration with subflowId, inputs, outputs, and dependencies
         */
        Subflow<TName extends string, TOutputNames extends readonly string[] = readonly string[]>(name: TName, config: Now.Internal.WithID<{
            /**
             * Unique identifier for the tool's capability record
             * Required to ensure stable identity across name changes
             * @example Now.ID['my_skill_subflow_tool']
             */
            $capabilityId: Now.Internal.ExplicitKey;
            /**
             * Reference to the subflow to call.
             * Accepts:
             * - A Subflow definition (same project - RECOMMENDED for type safety)
             * - A Now.ID reference for same-project subflows
             * - A raw sys_id string (fallback for external subflows)
             *
             * @example
             * // Using Subflow definition (same project - RECOMMENDED)
             * import { mySubflow } from './subflows/my-subflow.now'
             * subflowId: mySubflow
             *
             * // Using Now.ID reference (same project)
             * subflowId: Now.ID['my_subflow']
             *
             * // Using raw sys_id (external subflow)
             * subflowId: 'abc123def456...'
             */
            subflowId: string | SubflowRef;
            depends?: ToolDependency[];
            /**
             * Input mappings - array of { name, value } objects
             * Note: Input type is always 'string' for Subflow tools
             */
            inputs?: SubflowToolInput[];
            /**
             * Output definitions - array of { name, type?, truncate? } objects
             * Note: Outputs are DYNAMIC - they vary per subflow
             * If not specified, defaults to single 'Output' with type 'object'
             */
            outputs?: SubflowToolOutput[];
            /**
             * Whether to truncate all outputs (used when outputs is not specified)
             * @default false
             * @deprecated Use outputs array with truncate per output for fine-grained control
             */
            truncate?: boolean;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, TOutputNames>;
        /**
         * Create a Skill-as-Tool
         * Note: Input type is always 'string', Outputs have FIXED base + optional custom outputs
         * @param name - Unique tool name
         * @param config - Tool configuration with skillId, inputs, and dependencies
         */
        Skill<TName extends string>(name: TName, config: Now.Internal.WithID<{
            /**
             * Reference to the target skill's capability.
             * Accepts:
             * - A raw sys_id string (sys_one_extend_capability record)
             * - A NowAssistSkillConfig return value for same-project references
             * - DbRecord<'sys_one_extend_capability'> for explicit capability reference
             *
             * @example
             * // Using Now.ID reference (same project - RECOMMENDED)
             * skillId: Now.ID['helper_skill']
             *
             * // Using raw sys_id (external skill)
             * skillId: 'abc123def456...'
             *
             * // Using NowAssistSkillConfig variable (same project)
             * const HelperSkill = NowAssistSkillConfig({ $id: Now.ID['helper'], ... }, { ... })
             * skillId: HelperSkill
             *
             * // Using DbRecord reference
             * skillId: Now.Record('sys_one_extend_capability', 'abc123...')
             */
            skillId: string | ReturnType<typeof NowAssistSkillConfig> | DbRecord<'sys_one_extend_capability'>;
            depends?: ToolDependency[];
            /**
             * Input mappings - array of { definitionAttributeId, value } objects
             * Note: Input type is always 'string' for Skill tools
             */
            inputs?: SkillToolInput[];
            /**
             * Output mappings — includes the 5 mandatory base outputs plus any custom outputs.
             * Each output maps to a sys_one_extend_definition_attribute sys_id on the target skill.
             */
            outputs: SkillToolOutputs;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, readonly ['provider', 'response', 'error', 'errorcode', 'status']>;
        /**
         * Create a WebSearch tool
         * Note: Inputs are FIXED (two variants), Outputs are FIXED: provider, response, error, errorcode, status
         * @param name - Unique tool name
         * @param config - Tool configuration with search parameters
         */
        WebSearch<TName extends string>(name: TName, config: Now.Internal.WithID<(WebSearchAiAnswersConfig | WebSearchScrapingConfig) & {
            depends?: ToolDependency[];
            /**
             * Per-output truncate settings for the fixed outputs
             * Each output can be individually configured
             * @example { response: true, provider: false } // Only truncate response
             */
            truncate?: FixedOutputTruncateConfig;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, readonly ['provider', 'response', 'error', 'errorcode', 'status']>;
        /**
         * Create a Decision node for conditional branching
         *
         * Type-safe features:
         * - `targets`: Array of target tool names (IntelliSense works automatically)
         * - `branches.to`: Constrained to values from targets array
         * - `branches.condition.field`: Accepts t.input.* (string) or tool.output (ToolOutputRef)
         * - `default`: Constrained to values from targets array
         *
         * @param name - Unique decision node name
         * @param config - Decision configuration with targets, branches, and default path
         *
         * @example
         * ```typescript
         * const decision = t.Decision('Router', {
         *     $id: Now.ID['my_skill_router_decision'],
         *     depends: [previousTool],
         *     targets: ['PathA', 'PathB', 'PathC'],
         *     branches: (targets) => [
         *         {
         *             name: 'High Priority',
         *             to: targets.PathA,  // IntelliSense: 'PathA' | 'PathB' | 'PathC'
         *             condition: {
         *                 field: t.input.priority,  // Skill input reference
         *                 operator: 'is',
         *                 value: '1'
         *             }
         *         },
         *         {
         *             name: 'Tool Output Check',
         *             to: targets.PathB,
         *             condition: {
         *                 field: previousTool.output,  // Tool output reference
         *                 operator: 'contains',
         *                 value: 'error'
         *             }
         *         }
         *     ],
         *     default: (targets) => targets.PathC  // Type-safe default
         * })
         * ```
         */
        Decision<TName extends string, TTarget extends string, TDeps extends readonly BaseToolHandle[] = []>(name: TName, config: Now.Internal.WithID<{
            /**
             * Tools that must execute before this Decision node
             * Their outputs can be used in branch conditions via tool.output
             */
            depends?: TDeps;
            /**
             * Array of target tool names that branches can route to
             * IntelliSense works automatically - no need for `as const`
             * @example targets: ['ToolA', 'ToolB', 'ToolC']
             */
            targets: readonly TTarget[];
            /**
             * Branch definitions - each branch has a condition and target
             * @param targets - Object with target names as keys and values for type-safe access
             * @returns Array of branch configurations
             */
            branches: (targets: {
                [K in TTarget]: K;
            }) => DecisionBranch<TTarget>[];
            /**
             * Default target when no branch conditions match
             * @param targets - Object with target names as keys and values for type-safe access
             * @returns The default target name (type-safe, must be from targets array)
             */
            default: (targets: {
                [K in TTarget]: K;
            }) => TTarget;
            /**
             * Conditional execution - determines if tool should run
             * @default { type: 'none' }
             */
            condition?: ToolCondition;
        }>): ToolHandle<TName, readonly []>;
    }
    export {};
}
/**
 * ==========================================
 * NOW ASSIST SKILL CONFIGURATION API
 * ==========================================
 * This section defines the API structure that aligns with the ServiceNow UI
 * and provides a cleaner, more intuitive interface for skill configuration.
 */
/**
 * Skill definition — the first argument to NowAssistSkillConfig()
 * Contains all skill metadata, inputs, outputs, tools, and settings.
 *
 * TypeScript infers `TInputs` from the `inputs` property and `TTools` from the
 * `tools` callback return type. Because both live in this first argument,
 * they are fully resolved before the second argument (SkillPromptConfig)
 * is contextually typed, which guarantees correct IntelliSense for
 * `p.tool.*` and `p.input.*` in prompt builder callbacks.
 *
 * @example
 * ```typescript
 * // First argument to NowAssistSkillConfig():
 * {
 *   $id: Now.ID['life_tips_skill'],
 *   name: 'Life tips on user problem',
 *   shortDescription: 'Provides life tips',
 *   description: 'Life tips on user problem',
 *   inputs: [
 *     {
 *       $id: Now.ID['life_tips_user_problem_input'],
 *       name: 'user problem',
 *       description: 'Explain about user problem',
 *       mandatory: true,
 *       testValues: 'Having backpain since 2 days',
 *       dataType: 'string'
 *     }
 *   ],
 *   outputs: [
 *     // Standard outputs (required — only $id and name)
 *     { $id: Now.ID['life_tips_response_output'], name: 'response' },
 *     { $id: Now.ID['life_tips_provider_output'], name: 'provider' },
 *     { $id: Now.ID['life_tips_errorcode_output'], name: 'errorcode' },
 *     { $id: Now.ID['life_tips_status_output'], name: 'status' },
 *     { $id: Now.ID['life_tips_error_output'], name: 'error' },
 *   ],
 *   securityControls: {
 *     userAccess: { type: 'authenticated' },
 *     roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 *   }
 * }
 * ```
 */
export interface SkillDefinition<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>> {
    /** Display name shown in the NowAssist skill picker and admin views */
    name: string;
    /** Brief one-line summary displayed in skill listings and search results */
    shortDescription?: string;
    /** Detailed explanation of what the skill does, shown on the skill detail page */
    description?: string;
    /**
     * Skill state
     * Set to "published" to publish the skill (state = 1)
     * If not provided, skill will be in draft state (state = 0)
     * @example
     * // Draft skill (default)
     * { name: 'My Skill' }
     *
     * @example
     * // Published skill
     * { name: 'My Skill', state: 'published' }
     */
    state?: 'published';
    /**
     * Input attributes for the skill
     * Define as an inline array — type inference is automatic
     * @example
     * ```typescript
     * inputs: [
     *   { $id: Now.ID['my_skill_field_input'], name: 'field', dataType: 'string', mandatory: true }
     * ]
     * ```
     */
    inputs?: TInputs;
    /**
     * Skill output attributes (optional).
     * The 5 standard outputs (response, provider, errorcode, status, error) are always created.
     * If omitted or partially provided, missing standard outputs are auto-generated with derived IDs.
     * On transform, all outputs (including auto-generated ones) are synced back to code.
     *
     * @example
     * ```typescript
     * // Explicit standard outputs (recommended for stable identity)
     * outputs: [
     *   { $id: Now.ID['my_skill_response_output'], name: 'response', dataType: 'string' },
     *   { $id: Now.ID['my_skill_provider_output'], name: 'provider', dataType: 'string' },
     *   { $id: Now.ID['my_skill_errorcode_output'], name: 'errorcode', dataType: 'string' },
     *   { $id: Now.ID['my_skill_status_output'], name: 'status', dataType: 'string' },
     *   { $id: Now.ID['my_skill_error_output'], name: 'error', dataType: 'string' },
     *   { $id: Now.ID['my_custom_out'], name: 'myCustomField', dataType: 'string', description: 'Extra output' },
     * ]
     *
     * // Or omit entirely — standard outputs are auto-generated
     * ```
     */
    outputs?: OutputAttribute[];
    /**
     * Tool graph configuration (optional)
     * Define tools that the skill can use during execution
     *
     * **IMPORTANT:** Return tool handles to enable type-safe tool output access in prompts!
     *
     * **Supported Tool Types:**
     * - **Script**: Script Include execution
     * - **InlineScript**: Inline script execution
     * - **FlowAction**: Flow Action execution
     * - **Subflow**: Subflow execution
     * - **Skill**: Skill-as-Tool execution
     * - **WebSearch**: Web search capabilities
     * - **Decision**: Conditional branching logic
     *
     * @example
     * ```typescript
     * tools: (t) => ({
     *   createIncident: t.FlowAction('CreateIncident', {
     *     $id: Now.ID['my_skill_create_incident_tool'],
     *     actionId: 'flow_action_sys_id',
     *     inputs: [
     *       { name: 'short_description', type: 'string', value: t.input.incidentNumber },
     *       { name: 'priority', type: 'string', value: t.input.priority }
     *     ],
     *     outputs: [
     *       { name: 'sys_id', type: 'string' },
     *       { name: 'number', type: 'string' }
     *     ]
     *   }),
     *
     *   searchKB: t.WebSearch('SearchKB', {
     *     $id: Now.ID['my_skill_search_kb_tool'],
     *     searchType: 'ai_answers',
     *     query: t.input.query
     *   })
     * })
     * ```
     */
    tools?: (tools: NowAssistTools.ToolGraphBuilder<TInputs>) => TTools | void;
    /**
     * Skill-level settings including providers
     */
    skillSettings?: SkillSettings;
    /**
     * Deployment settings for UI Action and UI Builder
     */
    deploymentSettings?: DeploymentSettings;
    /**
     * Security controls for user access and role restrictions
     * MANDATORY: Must be provided for all skills
     * Defines who can access the skill and what roles it can inherit during execution
     * @example
     * ```typescript
     * securityControls: {
     *   userAccess: { type: 'authenticated' },
     *   roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
     * }
     * ```
     */
    securityControls: SecurityControls;
}
/**
 * Prompt configuration — the second argument to NowAssistSkillConfig()
 * Contains LLM provider configurations with their prompts.
 *
 * `NoInfer<TTools>` on the `providers` type prevents TypeScript from
 * inferring TTools from this argument, ensuring it is resolved solely
 * from the `tools` callback in the first argument.
 *
 * @example
 * ```typescript
 * // Second argument to NowAssistSkillConfig():
 * {
 *   providers: [
 *     {
 *       provider: 'Now LLM Service',
 *       prompts: [
 *         {
 *           name: 'Main Prompt',
 *           versions: [
 *             {
 *               $id: Now.ID['main_prompt_v1'],
 *               model: 'llm_generic_small',
 *               temperature: 0.2,
 *               promptState: 'published',
 *               prompt: (p) => `User says: ${p.input.question}`
 *             }
 *           ]
 *         }
 *       ]
 *     }
 *   ]
 * }
 * ```
 */
export interface SkillPromptConfig<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>> {
    /**
     * Array of providers with their prompts
     * Each provider can have multiple prompts
     * At least one prompt is required
     */
    providers: ProviderPromptConfig<TInputs, NoInfer<TTools>>[];
    /**
     * Name of the default provider (must match one provider's name)
     * If not specified, first provider is default
     *
     * **TYPE-SAFE:** When using `NowAssistSkillConfig()`, this is constrained
     * to the actual provider names defined in the `providers` array.
     */
    defaultProvider?: string;
}
/**
 * Mapped tuple type that validates per-provider constraints:
 * - `defaultPrompt` is constrained to actual prompt names defined in that provider
 * - `model` field gets per-provider autocomplete suggestions based on provider name
 * @internal
 */
type ValidatedProviders<TProviders extends readonly ProviderPromptConfig<TInputs, TTools, string>[], TInputs extends readonly InputAttribute[], TTools extends Record<string, BaseToolHandle>> = {
    [K in keyof TProviders]: TProviders[K] extends {
        provider: infer P extends string;
        prompts: readonly {
            name: infer N extends string;
        }[];
    } ? Omit<TProviders[K], 'defaultPrompt' | 'prompts'> & {
        prompts: PromptSettings<TInputs, TTools, P>[];
        defaultPrompt?: N;
    } : TProviders[K];
};
type ProviderFlowAPI = {
    type: 'sys_hub_flow';
    id: DbRecord<'sys_hub_flow'> | string;
} | {
    type: 'sys_hub_action_type_definition';
    id: DbRecord<'sys_hub_action_type_definition'> | string;
} | {
    type: 'sys_script_include';
    id: DbRecord<'sys_script_include'> | string;
} | {
    type: 'one_api_system_executor';
    id: string;
} | string;
/**
 * Known provider names with autocomplete support
 * Allows custom provider names as strings
 */
export type KnownProvider = StringWithSuggestions<'Now LLM Service' | 'Now LLM Generic' | 'Azure OpenAI' | 'Open AI' | 'Google Gemini' | 'AWS Claude' | 'IBM Watson' | 'Perplexity' | 'Custom LLM Provider' | 'Aleph Alpha'>;
/**
 * Model suggestions per provider - lookup table for autocomplete
 * @internal
 */
interface ProviderModelMap {
    'Now LLM Service': 'llm_generic_small_v2';
    'Now LLM Generic': 'llm_generic_small_v2';
    'Azure OpenAI': 'gpt-4' | 'gpt-4o-mini' | 'gpt_large';
    'Open AI': 'gpt-4' | 'gpt-4o-mini';
    OpenAI: 'gpt-4' | 'gpt-4o-mini';
    'Google Gemini': 'gemini-pro' | 'gemini_large';
    'AWS Claude': 'claude_large';
    'IBM Watson': 'ibm/granite-13b-chat-v2';
}
/**
 * Known model names per provider for autocomplete suggestions
 * Uses lookup table pattern instead of nested ternaries for better readability
 * Unknown providers fall back to plain string (no suggestions)
 * @internal
 */
type KnownModelsForProvider<P extends string> = P extends keyof ProviderModelMap ? ProviderModelMap[P] : string;
/**
 * Model type that offers per-provider autocomplete suggestions
 * Accepts any custom string regardless of provider
 * @internal
 */
type ModelForProvider<P extends string> = StringWithSuggestions<KnownModelsForProvider<P>>;
/**
 * Provider configuration with its prompts
 * Maps to sys_one_extend_capability_definition
 * Generic over TInputs and TTools to enable type-safe filterCondition and prompt builder
 */
export interface ProviderPromptConfig<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>, TProvider extends string = string> {
    /**
     * Provider name - use known providers for autocomplete or provide custom name
     *
     * Known providers (with autocomplete):
     * - `'Now LLM Service'` - ServiceNow's default LLM provider
     * - `'Azure OpenAI'` - Microsoft Azure OpenAI
     * - `'Open AI'` - OpenAI direct
     * - `'Google Gemini'` - Google Gemini/Vertex AI
     * - `'AWS Claude'` - Amazon Bedrock (Anthropic Claude)
     * - `'IBM Watson'` - IBM watsonx
     * - `'Perplexity'` - Perplexity AI
     * - `'Aleph Alpha'` - Aleph Alpha
     *
     * Or provide any custom provider name as a string.
     *
     * If `providerAPI` is not specified, the system will look up the default
     * flow implementation from PROVIDER_MAPPINGS based on this provider name.
     *
     * @example 'Now LLM Service'
     * @example 'Azure OpenAI'
     * @example 'My Custom Provider'
     */
    provider: KnownProvider;
    /**
     * Provider API configuration (optional)
     *
     * If not specified, the system will automatically look up the default
     * flow implementation based on the `provider` name .
     *
     * Provide this when:
     * - Using a custom provider
     * - Overriding the default flow for a known provider
     * - Specifying a non-default API for a provider (e.g., Azure OpenAI has multiple APIs)
     *
     * Maps to:
     * - sys_one_extend_capability_definition.api (the flow_id)
     * - sys_one_extend_capability_definition.api_type (the flow_type)
     *
     * @example
     * // Omit for known providers
     * provider: 'Now LLM Service'
     * // providerAPI not needed
     *
     * @example
     * // Object format for custom providers
     * provider: 'My Custom LLM',
     * providerAPI: {
     *   type: 'sys_hub_flow',
     *   id: 'my_flow_sys_id'
     * }
     *
     * @example
     * // String format (backward compatible - defaults to sys_hub_flow)
     * // Use the sys_id of your flow from the instance
     * providerAPI: '<your_flow_sys_id>'
     */
    providerAPI?: ProviderFlowAPI;
    /**
     * Array of prompts for this provider
     * At least one prompt is required
     */
    prompts: PromptSettings<TInputs, TTools, TProvider>[];
    /**
     * Name of the default prompt within this provider (must match one prompt's name)
     * If not specified, first prompt is default
     */
    defaultPrompt?: string;
    /**
     * Default version number for the default prompt
     * Specifies which version of the default prompt should be used
     * @example 1 or 2
     */
    defaultPromptVersion?: number;
}
/**
 * Prompt builder interface for type-safe inline prompts
 * Provides access to input fields and optionally tool outputs with autocomplete
 *
 * @typeParam TInputs - The input attributes for the skill
 * @typeParam TTools - Optional tool handles returned from the tools callback
 */
export interface PromptBuilder<TInputs extends readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>> {
    /**
     * Access input fields - returns template string like "{{input.fieldName}}"
     * @example
     * ```typescript
     * p.input.userQuestion  // Returns "{{input.userQuestion}}"
     * ```
     */
    readonly input: {
        readonly [K in TInputs[number]['name']]: string;
    };
    /**
     * Access tool outputs - returns template string like "{{toolName.fieldName}}"
     * Only available when tools callback returns tool handles
     * @example
     * ```typescript
     * p.tool.ScriptTool.output       // Single-output → "{{ScriptTool.output}}"
     * p.tool.WebSearch.response      // Multi-output  → "{{WebSearch.response}}"
     * ```
     */
    readonly tool: {
        readonly [K in keyof TTools]: TTools[K] extends {
            readonly [__toolOutputs]: infer TOutputs extends readonly string[];
        } ? {
            readonly [F in TOutputs[number]]: string;
        } : never;
    };
}
/**
 * Base prompt settings for prompt versions
 * Maps to sys_generative_ai_config fields
 * Generic over TInputs and TTools to enable type-safe prompt builder
 */
interface PromptSettingsBase<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>, TProvider extends string = string> {
    /**
     * Unique identifier for prompt
     * @example Now.ID['my_skill_prompt_v1']
     * */
    $id: Now.Internal.ExplicitKey;
    /**
     * Prompt version for tracking versions of same prompt
     * @default 1
     */
    version?: number;
    /**
     * Model name — autocomplete suggests known models for the selected provider
     * Accepts any custom string for instance-specific or custom models
     *
     * Known model suggestions per provider:
     * - **Now LLM Service / Now LLM Generic:** `'llm_generic_small'`, `'llm_generic_large'`, `'llm_generic_large_v2'`
     * - **Azure OpenAI:** `'gpt-4'`, `'gpt-4o-mini'`, `'gpt_large'`
     * - **Open AI:** `'gpt-4'`, `'gpt-4o-mini'`
     * - **Google Gemini:** `'gemini-pro'`, `'gemini_large'`
     * - **AWS Claude:** `'claude_large'`
     * - **IBM Watson:** `'ibm/granite-13b-chat-v2'`
     */
    model: ModelForProvider<TProvider>;
    /**
     * Temperature for LLM generation
     * @default 0.2
     */
    temperature?: number;
    /**
     * The actual prompt text - can be a string or a builder function
     *
     * **Option 1: Static string**
     * ```typescript
     * prompt: "You are a helpful assistant. User says: {{input.question}}"
     * ```
     *
     * **Option 2: Builder function (TYPE-SAFE!)** ✅
     * ```typescript
     * prompt: (p) => p.template`
     *   You are a helpful assistant.
     *   User question: ${p.input.question}
     *   Search results: ${p.tool.search.results}
     * `
     * ```
     *
     * The builder function provides:
     * - ✅ Autocomplete for input field names
     * - ✅ Autocomplete for tool output fields (when tools are defined)
     * - ✅ Type checking for field references
     * - ✅ No need for external variable
     */
    prompt: string | ((builder: PromptBuilder<TInputs, TTools>) => string);
    /**
     * Prompt state/status
     * - "draft": Prompt is in draft state
     * - "finalized": Prompt is finalized but not published
     * - "published": Prompt is published and active
     * - "archived": Prompt is archived (previous version)
     */
    promptState: 'draft' | 'finalized' | 'published' | 'archived';
    /**
     * Maximum tokens for response (required for non-"Now LLM Generic" providers)
     */
    maxTokens?: number;
    /**
     * Filter condition for prompt version usage (maps to "Usage conditions" in ServiceNow UI)
     * Defines when this prompt version should be used based on input attribute values
     *
     * In ServiceNow UI, this appears as:
     * - **Key dropdown:** Select from available input attributes
     * - **Value field:** Enter the condition value to match
     *
     * **TYPE-SAFE:** Keys can be:
     * - Original input names (e.g., `'User table'`, `'priority'`)
     * - Normalized name + dot-path for nested fields (e.g., `'user_table.building.country'`)
     *
     * Normalization converts spaces to underscores and lowercases: `'User table'` → `'user_table'`
     *
     * @example
     * // If you have inputs: [{ name: 'priority' }, { name: 'User table' }]
     * filterCondition: {
     *   'priority': 'high',                      // Original name
     *   'user_table.building.country': 'USA'    // Normalized + dot-path for nested field
     * }
     *
     * @example
     * // Multiple conditions (all must match)
     * filterCondition: {
     *   'priority': '1',
     *   'user_table.active': 'true'
     * }
     */
    filterCondition?: {
        [K in TInputs[number]['name'] | `${ToNormalized<TInputs[number]['name']>}.${string}`]?: string;
    };
}
/**
 * Prompt configuration with versioning support
 * Each prompt has a name and an array of prompt settings (versions)
 * Generic over TInputs and TTools to enable type-safe prompt builder
 */
export interface PromptSettings<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>, TProvider extends string = string> {
    /**
     * Unique prompt identifier within the provider
     * Must be unique within a skill
     */
    name: string;
    /**
     * Array of prompt settings for different versions
     * Each version represents a different configuration of the same prompt
     * Note: filterCondition is now set per version, not per prompt
     */
    versions: PromptSettingsBase<TInputs, TTools, TProvider>[];
}
/**
 * Common input attribute properties (without data_type and truncate)
 */
interface InputAttributeCommon {
    /** @example Now.ID['my_skill_user_query_input'] */
    $id: Now.Internal.ExplicitKey;
    /**
     * Attribute name - the internal name will be generated automatically
     * IMPORTANT: Must not contain underscores (_) or special characters
     */
    name: string;
    /** Description of the input attribute */
    description?: string;
    /**
     * Whether the input is mandatory
     * @default false
     */
    mandatory?: boolean;
    /**
     * Test values for the attribute
     * Used for testing and validation purposes
     */
    testValues?: string;
}
/**
 * Supported data types for input/output attributes
 * Maps to sys_one_extend_definition_attribute.data_type
 */
type AttributeDataType = 'string' | 'numeric' | 'boolean' | 'glide_record' | 'simple_array' | 'json_object' | 'json_array';
/**
 * Base input attribute properties
 */
interface InputAttributeBase extends InputAttributeCommon {
    /**
     * Data type for the input attribute
     * @default "string"
     */
    dataType: AttributeDataType;
    /**
     * Whether to truncate the value
     * NOTE: Only valid for: string, numeric, boolean, record, glide_record
     * NOT supported for: simple_array, json_object, json_array
     * @default false
     */
    truncate?: boolean;
}
/**
 * Input attribute definition
 * Maps to sys_one_extend_definition_attribute with type='input'
 *
 * **IMPORTANT:** When using `dataType: 'glide_record'`, `tableName` is REQUIRED.
 * Additionally, `tableSysId` is REQUIRED when `testValues` is provided.
 *
 * @example
 * // Correct usage with glide_record and testValues:
 * {
 *   $id: Now.ID['my_skill_incident_input'],
 *   name: 'Incident',
 *   description: '',
 *   mandatory: false,
 *   dataType: 'glide_record',
 *   truncate: false,
 *   testValues: 'INC0010001',
 *   tableName: 'incident',
 *   tableSysId: '9c963b7b33b776109c7c22c91e5c7b57',
 * }
 */
export type InputAttribute<T extends TableName = TableName> = InputAttributeBase & {
    /** Table name for glide_record type (REQUIRED when using glide_record dataType) */
    tableName?: T;
    /** Test record sys ID for glide_record type.**/
    tableSysId?: DbRecord<T> | string;
};
/**
 * Common output attribute properties (without data_type and truncate)
 */
interface OutputAttributeBase {
    /** @example Now.ID['my_skill_travel_response_output'] */
    $id: Now.Internal.ExplicitKey;
    /**
     * Attribute name - the internal name will be generated automatically
     * IMPORTANT: Must not contain underscores (_) or special characters
     */
    name: string;
    /** Description of the output attribute */
    description?: string;
    /** Data type for the output attribute */
    dataType: AttributeDataType;
}
/**
 * Output attribute definition
 * Maps to sys_one_extend_definition_attribute with type='output'
 *
 * **IMPORTANT:** When using `dataType: 'glide_record'`, `tableName` is REQUIRED.
 *
 * @example
 * // Correct usage with glide_record:
 * {
 *   $id: Now.ID['my_skill_related_record_output'],
 *   name: 'Related Record',
 *   dataType: 'glide_record',
 *   tableName: 'incident'
 * }
 */
export type OutputAttribute<T extends TableName = TableName> = OutputAttributeBase & {
    /** Table name for glide_record type (REQUIRED when using glide_record dataType) */
    tableName?: T;
};
/**
 * Skill-level settings including providers
 */
export interface SkillSettings {
    /** Provider configurations for preprocessing and postprocessing */
    providers: ProviderConfig[];
}
/**
 * Provider configuration for preprocessing and postprocessing
 * Maps to sys_generative_ai_validator and related tables
 * Requires exactly one of preprocessor or postprocessor to be defined (not both)
 */
export type ProviderConfig = {
    /**
     * Explicit ID for the validator record
     * Preserves validator identity across transform cycles
     * @example Now.ID['my_provider_validator']
     */
    $id: Now.Internal.ExplicitKey;
    /** Display name identifying this provider configuration, shown in admin views and used for defaultProvider matching */
    name: string;
    /**
     * Order in which this provider is evaluated
     * @default 100
     */
    order?: number;
} & ({
    /**
     * Preprocessor script - transforms request payload before sending to LLM
     *
     * @example
     * ```typescript
     * // String literal script
     * preprocessor: `(function(payload) {
     *   payload.transformedField = payload.inputField.toUpperCase();
     *   return payload;
     * })(payload);`
     *
     * // External file via Now.include()
     * preprocessor: Now.include('./scripts/preprocessor.js')
     * ```
     */
    preprocessor: string;
    postprocessor?: never;
} | {
    preprocessor?: never;
    /**
     * Postprocessor script - transforms response payload after receiving from LLM
     *
     * @example
     * ```typescript
     * // String literal script
     * postprocessor: `(function(payload) {
     *   payload.result = payload.response.trim();
     *   return payload;
     * })(payload);`
     *
     * // External file via Now.include()
     * postprocessor: Now.include('./scripts/postprocessor.js')
     * ```
     */
    postprocessor: string;
});
/**
 * Security controls for the skill
 * Defines who can access the skill and what roles it can inherit during execution
 *
 * @example
 * ```typescript
 * import { NowAssistSkillConfig } from '@servicenow/sdk/core'
 *
 * // Option 1: Authenticated users (any logged-in user)
 * securityControls: {
 *     userAccess: { type: 'authenticated' },
 *     roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 * }
 *
 * // Option 2: Role-based access with role names (RECOMMENDED)
 * securityControls: {
 *     userAccess: {
 *         type: 'roles',
 *         roles: ['admin', 'itil']
 *     },
 *     roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 * }
 *
 * // Option 3: Using sys_ids (portable across instances)
 * securityControls: {
 *     userAccess: {
 *         type: 'roles',
 *         roles: ['2831a114dbde1340d7d8a33be399c100']
 *     },
 *     roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 * }
 *
 * // Option 4: Using Now.ID references (for Fluent-defined roles)
 * securityControls: {
 *     userAccess: {
 *         type: 'roles',
 *         roles: [Now.ID['admin_role'], Now.ID['itil_role']]
 *     },
 *     roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 * }
 * ```
 */
export interface SecurityControls {
    /**
     * User Access - Define who can access and interact with this skill
     *
     * Type system enforces either 'authenticated' OR roles (not both)
     * Creates sys_security_acl (gen_ai_skill type) and sys_security_acl_role records
     * Automatically adds display_value attributes to generated XML
     *
     * **For authenticated users (any logged-in user):**
     * ```typescript
     * userAccess: {
     *     type: 'authenticated'
     * }
     * ```
     *
     * **For specific roles using role NAMES (RECOMMENDED - easier!):**
     * ```typescript
     * userAccess: {
     *     type: 'roles',
     *     roles: ['admin', 'itil']  // Role names - automatically resolved
     * }
     * ```
     *
     * **Or using sys_ids:**
     * ```typescript
     * userAccess: {
     *     type: 'roles',
     *     roles: ['2831a114dbde1340d7d8a33be399c100']  // admin role sys_id
     * }
     * ```
     *
     * @note Type system prevents specifying both authenticated AND roles
     */
    userAccess: UserAccessConfig;
    /**
     * Role Restrictions - Defines which roles the skill can inherit from the invoking user
     * MANDATORY: Must provide at least one role
     * Ensures the skill does not access more resources than necessary
     * Role names are NOT supported
     *
     * @example
     * roleRestrictions: ['2831a114c611228501d4ea6c309d626d'] // admin role sys_id
     * roleRestrictions: ['2831a114c611228501d4ea6c309d626d', 'b85d44954a3623120004689b2d5dd60a'] // multiple roles
     */
    roleRestrictions: (string | Role | DbRecord<'sys_user_role'>)[];
}
/**
 * UI Action auto-generation configuration
 * Simplified API - only table name required, everything else is auto-generated
 * Fields derived from SDK UiAction type for consistency
 */
export type UIActionConfig = Now.Internal.WithID<Required<Pick<UiAction<TableName>, 'table'>> & Partial<Pick<UiAction<TableName>, 'name' | 'condition' | 'active'>> & {
    /**
     * Script that runs when the UI Action is triggered
     * @default auto-generated script that invokes the skill
     */
    script?: string;
}>;
/**
 * Now Assist Platform (NAP) deployment configuration
 * Configures NAP deployment with required roles for panel access
 */
export interface NowAssistPanelConfig {
    /**
     * Enable NAP deployment
     */
    enabled: true;
    /**
     * Roles that can access this skill in the Now Assist Panel
     * Must include 'now_assist_panel_user' for NAP access
     *
     * Supports:
     * - Role name strings (e.g., 'now_assist_panel_user')
     * - Role sys_id strings
     * - Role objects created with Role()
     * - DbRecord references to sys_user_role
     *
     * @example roles: ['now_assist_panel_user', 'access_analyzer_ai_user']
     */
    roles: (string | Role | DbRecord<'sys_user_role'>)[];
}
/**
 * Deployment settings for Now Assist skills
 * Configures where and how the skill should be deployed
 */
export interface DeploymentSettings {
    /**
     * UI Action deployment configuration
     *
     * Auto-generation creates:
     * - sys_ui_action record with skill invocation script
     * - sys_ux_form_action record for UI compatibility
     * - Condition checking if skill is active
     * - Auto-mapped inputs from promptConfiguration
     *
     * All fields except `table` are optional — defaults are auto-generated:
     * - `name` defaults to skill name
     * - `condition` defaults to skill active check
     * - `script` defaults to skill invocation script
     * - `active` defaults to false
     *
     * **Note:** The target table must have `actions_access: true` to allow UI Actions.
     *
     * @example
     * // (recommended):
     * uiAction: { $id: Now.ID['my_skill_uiaction'], table: 'incident' }
     *
     */
    uiAction?: UIActionConfig;
    /**
     * Now Assist Platform (NAP) deployment configuration
     * Enables deployment to Now Assist Platform
     *
     * @example
     * // Basic NAP deployment with required role
     * nowAssistPanel: {
     *   enabled: true,
     *   roles: ['now_assist_panel_user']
     * }
     *
     * @example
     * // NAP deployment with multiple roles
     * nowAssistPanel: {
     *   enabled: true,
     *   roles: ['now_assist_panel_user', 'access_analyzer_ai_user']
     * }
     */
    nowAssistPanel?: NowAssistPanelConfig;
    /**
     * Flow Action / Workflow Trigger deployment configuration
     * Creates a View Trigger configuration step that enables workflow triggers
     * @example flowAction: true
     */
    flowAction?: true;
    /**
     * Skill family to associate this skill with in the Now Assist admin panel.
     * Accepts either a sys_id string or a record reference to an existing
     * sn_nowassist_skill_family record.
     * If not provided, defaults to the "Others" skill family.
     *
     * @example
     * // By sys_id string
     * skillFamily: 'dd4d92572fe7be10ac5ed15fafa4e3d4'
     *
     * @example
     * // By record reference
     * skillFamily: Record({ table: 'sn_nowassist_skill_family', data: { name: 'My Family' } })
     */
    skillFamily?: string | DbRecord<'sn_nowassist_skill_family'>;
}
/**
 * ==========================================
 * API EXPORT
 * ==========================================
 */
/**
 * Type representing the skill definition with $id for ServiceNow record identification
 * Generic over TInputs and TTools to preserve type safety through the entire configuration
 */
export type SkillDefinitionWithID<TInputs extends readonly InputAttribute[] = readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>> = Now.Internal.WithID<SkillDefinition<TInputs, TTools>>;
/**
 * Creates a NowAssist Skill configuration
 *
 * Takes two arguments to solve the IntelliSense ordering problem:
 * - **Arg 1 (definition):** Skill metadata, inputs, outputs, tools, security
 * - **Arg 2 (promptConfig):** LLM provider configurations with prompts
 *
 * TypeScript infers function arguments LEFT-TO-RIGHT, so `TInputs` and `TTools`
 * are fully resolved from arg 1 before arg 2 needs them. This guarantees
 * `p.tool.*` and `p.input.*` IntelliSense works regardless of property order.
 *
 * @param definition - Skill definition including name, inputs, outputs, tools, and settings
 * @param promptConfig - Provider and prompt configurations
 *
 * @example
 * ```typescript
 * // Basic skill without tools
 * NowAssistSkillConfig(
 *   {
 *     $id: Now.ID['my_skill'],
 *     name: 'Customer Support Helper',
 *     shortDescription: 'Helps with customer inquiries',
 *     description: 'AI-powered customer support assistant',
 *     inputs: [
 *       {
 *         name: 'customer_inquiry',
 *         description: 'Customer question or issue',
 *         mandatory: true,
 *         dataType: 'string'
 *       }
 *     ],
 *     outputs: [
 *       { $id: Now.ID['my_skill_response_output'], name: 'response' },
 *       { $id: Now.ID['my_skill_provider_output'], name: 'provider' },
 *       { $id: Now.ID['my_skill_errorcode_output'], name: 'errorcode' },
 *       { $id: Now.ID['my_skill_status_output'], name: 'status' },
 *       { $id: Now.ID['my_skill_error_output'], name: 'error' },
 *     ],
 *     securityControls: {
 *       userAccess: { type: 'authenticated' },
 *       roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 *     }
 *   },
 *   {
 *     providers: [
 *       {
 *         provider: 'Now LLM Service',
 *         prompts: [
 *           {
 *             name: 'Support Prompt',
 *             versions: [
 *               {
 *                 version: 1,
 *                 model: 'llm_generic_small',
 *                 temperature: 0.3,
 *                 prompt: 'You are a helpful customer support agent...',
 *                 promptState: 'published'
 *               }
 *             ]
 *           }
 *         ]
 *       }
 *     ]
 *   }
 * )
 *
 * // Skill with tools — TTools inferred from arg 1, available in arg 2 prompts
 * NowAssistSkillConfig(
 *   {
 *     $id: Now.ID['incident_skill'],
 *     name: 'Incident Processing Skill',
 *     inputs: [
 *       { name: 'incidentNumber', dataType: 'string', mandatory: true },
 *       { name: 'priority', dataType: 'string', mandatory: false }
 *     ],
 *     outputs: [
 *       { $id: Now.ID['inc_response_output'], name: 'response' },
 *       { $id: Now.ID['inc_provider_output'], name: 'provider' },
 *       { $id: Now.ID['inc_errorcode_output'], name: 'errorcode' },
 *       { $id: Now.ID['inc_status_output'], name: 'status' },
 *       { $id: Now.ID['inc_error_output'], name: 'error' },
 *     ],
 *     tools: (t) => ({
 *       FetchIncident: t.Script('FetchIncident', {
 *         scriptId: 'script_sys_id',
 *         inputs: [{ name: 'num', value: t.input.incidentNumber }]
 *       })
 *     }),
 *     securityControls: {
 *       userAccess: { type: 'authenticated' },
 *       roleRestrictions: ['2831a114c611228501d4ea6c309d626d']
 *     }
 *   },
 *   {
 *     providers: [
 *       {
 *         provider: 'Now LLM Service',
 *         prompts: [
 *           {
 *             name: 'Main Prompt',
 *             versions: [
 *               {
 *                 model: 'llm_generic_small',
 *                 promptState: 'published',
 *                 prompt: (p) => `
 *                   Incident: ${p.input.incidentNumber}
 *                   Data: ${p.tool.FetchIncident.Output}
 *                 `
 *               }
 *             ]
 *           }
 *         ]
 *       }
 *     ]
 *   }
 * )
 * ```
 */
export declare function NowAssistSkillConfig<const TInputs extends readonly InputAttribute[], TTools extends Record<string, BaseToolHandle> = Record<string, BaseToolHandle>, const TProviders extends readonly ProviderPromptConfig<TInputs, TTools>[] = readonly ProviderPromptConfig<TInputs, TTools>[]>(definition: SkillDefinitionWithID<TInputs, TTools>, promptConfig: {
    providers: [...ValidatedProviders<TProviders, TInputs, TTools>];
    defaultProvider?: TProviders[number]['provider'];
}): [SkillDefinitionWithID<TInputs, TTools>, SkillPromptConfig<TInputs, TTools>];
export {};
