// retoor #include "r_config.h" #include #include #include #include struct r_config_t { char *api_url; char *models_url; char *model; char *api_key; char *db_path; char *session_id; char *system_message; char *current_prompt; double temperature; int max_tokens; int max_spawn_depth; int max_total_spawns; bool use_tools; bool use_strict; bool verbose; }; static struct r_config_t *instance = NULL; static char *strdup_safe(const char *s) { return s ? strdup(s) : NULL; } static bool resolve_env_bool(const char *env_name, bool default_val) { const char *val = getenv(env_name); if (!val) return default_val; if (!strcmp(val, "true") || !strcmp(val, "1")) return true; if (!strcmp(val, "false") || !strcmp(val, "0")) return false; return default_val; } static const char *resolve_api_key(void) { const char * key = getenv("R_KEY"); if (key && *key) return key; key = getenv("OPENROUTER_API_KEY"); if (key && *key) return key; key = getenv("OPENAI_API_KEY"); if (key && *key) return key; return "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"; } static bool is_valid_session_id(const char *session_id) { if (!session_id || !*session_id) return false; if (strlen(session_id) > 255) return false; for (const char *p = session_id; *p; p++) { if (!isalnum((unsigned char)*p) && *p != '-' && *p != '_' && *p != '.') { return false; } } return true; } r_config_handle r_config_get_instance(void) { if (instance) return instance; instance = calloc(1, sizeof(struct r_config_t)); if (!instance) return NULL; const char *base_url = getenv("R_BASE_URL"); if (base_url && *base_url) { size_t len = strlen(base_url); instance->api_url = malloc(len + 32); instance->models_url = malloc(len + 32); if (instance->api_url && instance->models_url) { snprintf(instance->api_url, len + 32, "%s/v1/chat/completions", base_url); snprintf(instance->models_url, len + 32, "%s/v1/models", base_url); } } else { instance->api_url = strdup("https://api.openai.com/v1/chat/completions"); instance->models_url = strdup("https://api.openai.com/v1/models"); } const char *model = getenv("R_MODEL"); instance->model = strdup(model && *model ? model : "gpt-4o-mini"); instance->api_key = strdup(resolve_api_key()); instance->db_path = strdup("~/.r.db"); instance->temperature = 0.1; const char *max_tokens_env = getenv("R_MAX_TOKENS"); instance->max_tokens = max_tokens_env ? atoi(max_tokens_env) : 4096; const char *spawn_depth_env = getenv("R_MAX_SPAWN_DEPTH"); instance->max_spawn_depth = spawn_depth_env ? atoi(spawn_depth_env) : 5; const char *total_spawns_env = getenv("R_MAX_TOTAL_SPAWNS"); instance->max_total_spawns = total_spawns_env ? atoi(total_spawns_env) : 20; instance->use_tools = resolve_env_bool("R_USE_TOOLS", true); instance->use_strict = resolve_env_bool("R_USE_STRICT", true); instance->verbose = false; const char *session = getenv("R_SESSION"); if (session && is_valid_session_id(session)) { instance->session_id = strdup(session); } else { instance->session_id = NULL; } instance->system_message = strdup_safe(getenv("R_SYSTEM_MESSAGE")); return instance; } void r_config_destroy(void) { if (!instance) return; free(instance->api_url); free(instance->models_url); free(instance->model); free(instance->api_key); free(instance->db_path); free(instance->session_id); free(instance->system_message); free(instance->current_prompt); free(instance); instance = NULL; } const char *r_config_get_api_url(r_config_handle cfg) { return cfg ? cfg->api_url : NULL; } const char *r_config_get_models_url(r_config_handle cfg) { return cfg ? cfg->models_url : NULL; } const char *r_config_get_model(r_config_handle cfg) { return cfg ? cfg->model : NULL; } void r_config_set_model(r_config_handle cfg, const char *model) { if (!cfg || !model) return; free(cfg->model); cfg->model = strdup(model); } const char *r_config_get_api_key(r_config_handle cfg) { return cfg ? cfg->api_key : NULL; } const char *r_config_get_db_path(r_config_handle cfg) { return cfg ? cfg->db_path : NULL; } bool r_config_use_tools(r_config_handle cfg) { return cfg ? cfg->use_tools : true; } bool r_config_use_strict(r_config_handle cfg) { return cfg ? cfg->use_strict : true; } bool r_config_is_verbose(r_config_handle cfg) { return cfg ? cfg->verbose : false; } void r_config_set_verbose(r_config_handle cfg, bool verbose) { if (cfg) cfg->verbose = verbose; } double r_config_get_temperature(r_config_handle cfg) { return cfg ? cfg->temperature : 0.1; } int r_config_get_max_tokens(r_config_handle cfg) { return cfg ? cfg->max_tokens : 4096; } const char *r_config_get_session_id(r_config_handle cfg) { return cfg ? cfg->session_id : NULL; } bool r_config_set_session_id(r_config_handle cfg, const char *session_id) { if (!cfg || !is_valid_session_id(session_id)) return false; free(cfg->session_id); cfg->session_id = strdup(session_id); return cfg->session_id != NULL; } const char *r_config_get_system_message(r_config_handle cfg) { return cfg ? cfg->system_message : NULL; } int r_config_get_max_spawn_depth(r_config_handle cfg) { return cfg ? cfg->max_spawn_depth : 5; } int r_config_get_max_total_spawns(r_config_handle cfg) { return cfg ? cfg->max_total_spawns : 20; } void r_config_set_current_prompt(r_config_handle cfg, const char *prompt) { if (!cfg) return; free(cfg->current_prompt); cfg->current_prompt = prompt ? strdup(prompt) : NULL; } const char *r_config_get_current_prompt(r_config_handle cfg) { return cfg ? cfg->current_prompt : NULL; } /* * Deepsearch Algorithm System Instructions * * Based on research into Deep Research/Deep Search algorithms from * OpenAI Deep Research, Gemini Deep Research, and academic sources. * * This implements an iterative, multi-step research process that goes * far beyond simple search to produce comprehensive, well-sourced reports. */ const char *r_config_get_deepsearch_system_message(void) { return "You are an advanced Deep Research Agent. When DEEPSEARCH is invoked, you MUST execute the following comprehensive algorithm using the web search tool. This is an iterative, multi-step research process - not a single search query.\n" "\n" "=== DEEPSEARCH ALGORITHM EXECUTION ===\n" "\n" "PHASE 1: INTENT CLARIFICATION (Human-in-the-loop)\n" "- Analyze the user's research query for ambiguity, missing context, or scope issues\n" "- Generate 2-4 clarifying questions to refine the research direction\n" "- Combine original query with user responses to form the RESEARCH OBJECTIVE\n" "- Define SCOPE boundaries: time period, geographic region, technical depth, etc.\n" "\n" "PHASE 2: RESEARCH PLANNING\n" "- Decompose the RESEARCH OBJECTIVE into 3-7 distinct sub-topics or research questions\n" "- For each sub-topic, identify: key entities, required data types, credible source types\n" "- Create a RESEARCH PLAN: ordered list of investigation areas with priorities\n" "- Determine ITERATION PARAMETERS: max_depth (3-5 recommended), breadth_per_level (5-10 queries)\n" "\n" "PHASE 3: ITERATIVE SEARCH LOOP (Core Algorithm)\n" "Execute the following loop until depth=0 or sufficient information gathered:\n" "\n" " 3.1 QUERY GENERATION\n" " - Based on current RESEARCH OBJECTIVE and accumulated LEARNINGS\n" " - Generate breadth_per_level search queries that are:\n" " * Diverse: cover different angles, perspectives, and source types\n" " * Specific: narrowly focused on particular aspects, not broad queries\n" " * Progressive: build upon previous learnings, drilling deeper\n" " * Evidence-seeking: designed to find data, quotes, statistics, citations\n" "\n" " 3.2 CONCURRENT SEARCH EXECUTION\n" " - Execute ALL generated queries in parallel using the web search tool\n" " - For each result, capture: URL, title, publication date, author/source credibility\n" " - Maintain SEARCH LOG: record all queries executed and URLs visited\n" "\n" " 3.3 CONTENT EXTRACTION & PARSING\n" " - For top-ranked results (based on relevance and source credibility):\n" " - Extract main content, filtering out: navigation, ads, footers, unrelated sections\n" " - Preserve: key facts, statistics, expert quotes, dates, named entities, citations\n" " - Flag content quality: authoritative (academic/government), credible (news/expert), or unverified\n" "\n" " 3.4 LEARNING EXTRACTION\n" " - For each extracted content piece, generate LEARNINGS:\n" " * Key findings relevant to sub-topics\n" " * Direct quotes with attribution\n" " * Statistics and data points with sources\n" " * Named entities and their relationships\n" " * Dates and temporal information\n" " * Citations to other authoritative sources\n" " - Deduplicate: merge similar findings from multiple sources\n" " - Cross-validate: mark facts confirmed by multiple independent sources\n" "\n" " 3.5 GAP ANALYSIS & FOLLOW-UP\n" " - Analyze current LEARNINGS against RESEARCH PLAN\n" " - Identify KNOWLEDGE GAPS:\n" " * Missing information needed to answer research questions\n" " * Conflicting information requiring resolution\n" " * Areas with insufficient source diversity\n" " * Claims needing fact-checking\n" " - Generate 3-5 FOLLOW-UP QUESTIONS to address gaps\n" "\n" " 3.6 ITERATION CONTROL\n" " - If depth > 0 AND knowledge gaps exist:\n" " * depth = depth - 1\n" " * Update RESEARCH OBJECTIVE with FOLLOW-UP QUESTIONS\n" " * Continue to next iteration (return to 3.1)\n" " - If depth = 0 OR sufficient information gathered:\n" " * Exit loop and proceed to Phase 4\n" "\n" "PHASE 4: SYNTHESIS & VERIFICATION\n" "- Organize all LEARNINGS by sub-topic from RESEARCH PLAN\n" "- Cross-source verification:\n" " * Identify and resolve conflicting claims between sources\n" " * Prioritize authoritative sources for disputed facts\n" " * Flag uncertain information requiring caveats\n" "- Evidence quality assessment:\n" " * Mark high-confidence facts (multiple authoritative sources)\n" " * Mark medium-confidence facts (limited sources or expert opinion)\n" " * Note low-confidence or speculative claims\n" "\n" "PHASE 5: STRUCTURED REPORT GENERATION\n" "- Generate comprehensive research report with the following structure:\n" "\n" " EXECUTIVE SUMMARY\n" " - 2-4 paragraph overview of key findings\n" " - Direct answer to original research query if possible\n" "\n" " KEY FINDINGS\n" " - Numbered list of 5-10 major findings\n" " - Each finding with inline citation [Source: URL or publication]\n" "\n" " DETAILED ANALYSIS (by sub-topic)\n" " - For each research sub-topic from Phase 2:\n" " * Section header with sub-topic name\n" " * Comprehensive analysis with supporting evidence\n" " * Relevant statistics, quotes, and data points\n" " * Citations for all claims\n" "\n" " SOURCE EVALUATION\n" " - List of primary sources consulted (grouped by credibility tier)\n" " - Methodology note: search strategies used, limitations encountered\n" "\n" " REMAINING UNCERTAINTIES\n" " - Gaps that could not be filled within search constraints\n" " - Areas where sources conflicted or were insufficient\n" " - Recommendations for further research\n" "\n" "PHASE 6: CITATION FORMATTING\n" "- Use inline citations: [Author/Source, Year] or [Publication Name]\n" "- Include full reference list at end with URLs\n" "- Ensure every significant claim has attribution\n" "\n" "=== ALGORITHM CONSTRAINTS ===\n" "- MINIMUM ITERATIONS: At least 3 search iterations (depth >= 2)\n" "- SOURCE DIVERSITY: Aim for at least 5 distinct authoritative sources\n" "- TEMPORAL COVERAGE: Include both recent and foundational sources\n" "- PERSPECTIVE DIVERSITY: Seek multiple viewpoints on controversial topics\n" "- AVOID PLAGIARISM: Paraphrase and synthesize; use quotes sparingly with attribution\n" "\n" "=== STOP CONDITIONS ===\n" "Stop iterating when ANY of:\n" "1. Knowledge gaps have been sufficiently filled to answer the research question\n" "2. Maximum depth reached (configured in iteration parameters)\n" "3. Diminishing returns: new searches not yielding novel information\n" "4. Sufficient source diversity and cross-validation achieved\n" "\n" "Execute this algorithm methodically. Report your progress through each phase. Maintain the SEARCH LOG and LEARNINGS accumulation throughout. Produce the final structured report in Phase 5."; }