import { __awaiter } from "tslib";
/**
 * Symbol used to attach ToolFold metadata to a facade handler function.
 * The ChatDriver inspects this to detect fold facades at runtime.
 *
 * @internal
 */
export const TOOL_FOLD_SYMBOL = Symbol('toolFold');
/**
 * Creates a tool fold — a facade that hides a group of related tools behind a single
 * named entry, revealing them progressively when the model invokes the facade.
 *
 * The `tools` and `handlers` parameters accept the exact same types as `AgentConfig.toolDefinitions`
 * and `AgentConfig.toolHandlers`, so existing tool creation functions can be passed in unchanged.
 *
 * @example
 * ```typescript
 * const tradingTools = createToolFold({
 *   name: 'trading_tools',
 *   tools: createTradesToolDefinitions(),
 *   handlers: createTradesToolHandlers(connect),
 * });
 *
 * const agent: AgentConfig = {
 *   name: 'Trades',
 *   systemPrompt: '...',
 *   toolDefinitions: [getCurrentDateDef, tradingTools.definition],
 *   toolHandlers: { get_current_date: handler, ...tradingTools.handler },
 * };
 * ```
 *
 * @example Nesting folds
 * ```typescript
 * const insertFold = createToolFold({
 *   name: 'trade_insertion',
 *   tools: [validateDef, insertDef],
 *   handlers: { validate_trade: vHandler, insert_trade: iHandler },
 * });
 *
 * const tradingFold = createToolFold({
 *   name: 'trading_tools',
 *   tools: [searchDef, insertFold.definition],
 *   handlers: { search_trades: sHandler, ...insertFold.handler },
 * });
 * ```
 *
 * @beta
 */
export function createToolFold(config) {
    var _a, _b;
    const description = (_a = config.description) !== null && _a !== void 0 ? _a : `Contains: ${config.tools.map((t) => t.name).join(', ')}. Invoke to access these tools.`;
    const fold = {
        name: config.name,
        description,
        usageNotes: config.usageNotes,
        tools: config.tools,
        handlers: config.handlers,
        exclusive: (_b = config.exclusive) !== null && _b !== void 0 ? _b : true,
    };
    const definition = {
        name: config.name,
        description,
        parameters: { type: 'object', properties: {} },
    };
    // The facade handler body is never actually called — the driver intercepts it
    // via TOOL_FOLD_SYMBOL before dispatch. The body is a no-op fallback.
    const facadeHandler = () => __awaiter(this, void 0, void 0, function* () { return `Fold: ${config.name}`; });
    facadeHandler[TOOL_FOLD_SYMBOL] = fold;
    return {
        definition,
        handler: {
            [config.name]: facadeHandler,
        },
    };
}
/**
 * Expands a flat list of tool definitions into a nested tree by resolving fold
 * metadata from the corresponding handlers. Use this for debug output so the
 * full tool hierarchy is visible rather than just the top-level facade names.
 *
 * @beta
 */
export function expandToolTree(definitions, handlers) {
    return definitions.map((def) => {
        const handler = handlers[def.name];
        const fold = handler ? handler[TOOL_FOLD_SYMBOL] : undefined;
        if (fold) {
            return Object.assign(Object.assign({}, def), { tools: expandToolTree(fold.tools, fold.handlers) });
        }
        return Object.assign({}, def);
    });
}
