Use this file to discover all available pages before exploring further.
A multi-turn ReAct-style financial-QA agent that answers questions about SEC 10-K financial statements by querying structured tables. Four tools are exposed via native OpenAI function calling.
Downloads the rLLM/finqa tarball, extracts company tables to cookbooks/finqa/data/company_tables/, and registers finqa/{train, val, test} (4,030 / 522 / 558 rows).The data tree is large (~6,900 tables) — use FINQA_TABLES_ROOT env var to point at a shared mount if you have one.
The flow is the canonical multi-turn-tool-call template:
@rllm.rollout(name="finqa")async def finqa_flow(task: Task, config: AgentConfig) -> Episode: client = AsyncOpenAI(base_url=config.base_url, api_key="EMPTY") messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": task.metadata.get("question")}, ] accessed_tables, steps, final = [], [], "" for turn in range(MAX_TURNS): resp = await client.chat.completions.create( model=config.model, messages=messages, tools=TOOL_SPECS, ..., ) msg = resp.choices[0].message messages.append(_msg_to_dict(msg)) steps.append(Step(chat_completions=list(messages), model_response=msg.content or "", ...)) if not msg.tool_calls: final = msg.content or "" break for tc in msg.tool_calls: output = _exec_tool_call(tc, accessed_tables) messages.append({"role": "tool", "tool_call_id": tc.id, "content": output}) return Episode( trajectories=[Trajectory(name="finqa", steps=steps)], artifacts={"answer": final, "accessed_tables": accessed_tables, "turns": len(steps)}, )
Tools are plain Python callables paired with an OpenAI function spec — no Tool base class, no registry. The 4 tools share a process-wide SQLite store loaded once at module import: