33 ensureScaffold ,
44 hasSemanticScholarApiKey ,
55 loadConfig ,
6+ resolveOpenAiApiKey ,
67 resolveAppPaths ,
78 resolveSemanticScholarApiKey ,
89 runSetupWizard ,
@@ -14,19 +15,19 @@ import { CodexCliClient } from "./integrations/codex/codexCliClient.js";
1415import { AgentOrchestrator } from "./core/agents/agentOrchestrator.js" ;
1516import { launchTerminalApp } from "./tui/TerminalApp.js" ;
1617import { InMemoryEventStream } from "./core/events.js" ;
17- import { CodexLLMClient } from "./core/llm/client.js" ;
18+ import { CodexLLMClient , OpenAiResponsesLLMClient , RoutedLLMClient } from "./core/llm/client.js" ;
1819import { LocalAciAdapter } from "./tools/aciLocalAdapter.js" ;
1920import { SemanticScholarClient } from "./tools/semanticScholar.js" ;
2021import { DefaultNodeRegistry } from "./core/stateGraph/nodeRegistry.js" ;
2122import { CheckpointStore } from "./core/stateGraph/checkpointStore.js" ;
2223import { StateGraphRuntime } from "./core/stateGraph/runtime.js" ;
2324import { askLine } from "./utils/prompt.js" ;
2425import { AppConfig } from "./types.js" ;
26+ import { ResponsesPdfAnalysisClient } from "./integrations/openai/responsesPdfAnalysisClient.js" ;
27+ import { OpenAiResponsesTextClient } from "./integrations/openai/responsesTextClient.js" ;
2528
2629export async function runAutoresearchApp ( ) : Promise < void > {
2730 const paths = resolveAppPaths ( process . cwd ( ) ) ;
28- await ensureScaffold ( paths ) ;
29-
3031 const firstRunSetup = ! ( await configExists ( paths ) ) ;
3132 let config ;
3233 if ( firstRunSetup ) {
@@ -36,14 +37,21 @@ export async function runAutoresearchApp(): Promise<void> {
3637 } else {
3738 config = await loadConfig ( paths ) ;
3839 }
40+ await ensureScaffold ( paths ) ;
3941
4042 const runStore = new RunStore ( paths ) ;
4143 const codex = new CodexCliClient ( paths . cwd , {
4244 model : config . providers . codex . model || "gpt-5.3-codex" ,
4345 reasoningEffort : config . providers . codex . reasoning_effort || "xhigh" ,
4446 fastMode : config . providers . codex . fast_mode === true
4547 } ) ;
46- const titleGenerator = new TitleGenerator ( codex ) ;
48+ const openAiText = new OpenAiResponsesTextClient ( ( ) => resolveOpenAiApiKey ( paths . cwd ) , {
49+ model : config . providers . openai . model ,
50+ reasoningEffort : config . providers . openai . reasoning_effort
51+ } ) ;
52+ const titleGenerator = new TitleGenerator ( ( ) =>
53+ config . providers . llm_mode === "openai_api" ? openAiText : codex
54+ ) ;
4755 const initialRunId = await maybeCreateInitialRun ( {
4856 firstRunSetup,
4957 runStore,
@@ -52,14 +60,19 @@ export async function runAutoresearchApp(): Promise<void> {
5260 } ) ;
5361
5462 const eventStream = new InMemoryEventStream ( ) ;
55- const llm = new CodexLLMClient ( codex ) ;
63+ const codexLlm = new CodexLLMClient ( codex ) ;
64+ const openAiLlm = new OpenAiResponsesLLMClient ( openAiText ) ;
65+ const llm = new RoutedLLMClient ( ( ) =>
66+ config . providers . llm_mode === "openai_api" ? openAiLlm : codexLlm
67+ ) ;
5668 const aci = new LocalAciAdapter ( ) ;
5769 const semanticScholarApiKey = await resolveSemanticScholarApiKey ( paths . cwd ) ;
5870 const semanticScholar = new SemanticScholarClient ( {
5971 apiKey : semanticScholarApiKey ,
6072 perSecondLimit : config . papers . per_second_limit ,
6173 maxRetries : 3
6274 } ) ;
75+ const responsesPdfAnalysis = new ResponsesPdfAnalysisClient ( ( ) => resolveOpenAiApiKey ( paths . cwd ) ) ;
6376
6477 const nodeRegistry = new DefaultNodeRegistry ( {
6578 config,
@@ -68,7 +81,8 @@ export async function runAutoresearchApp(): Promise<void> {
6881 llm,
6982 codex,
7083 aci,
71- semanticScholar
84+ semanticScholar,
85+ responsesPdfAnalysis
7286 } ) ;
7387
7488 const checkpointStore = new CheckpointStore ( paths ) ;
@@ -80,6 +94,7 @@ export async function runAutoresearchApp(): Promise<void> {
8094 runStore,
8195 titleGenerator,
8296 codex,
97+ openAiTextClient : openAiText ,
8398 eventStream,
8499 orchestrator,
85100 initialRunId,
0 commit comments