Summary
The runtime preflight only checks SERPER_API_KEY and JINA_API_KEY when the
active mode is research. The CLI won't let you pick that mode. It accepts
react and agent_team, and both bind web_search and web_fetch. So you can
start with no search key, see a clean preflight, and only find out when the
model gets an error string back from its first search.
Details
apodex/config.py:150:
if active_mode == "research":
if not _configured(env.get("SERPER_API_KEY")):
...
active_mode is mode or profile.name, and cli.py passes whichever mode the
user picked. apodex/profiles/__init__.py:32 caps that list:
_TERMINAL_WORKFLOW_MODES = ("react", "agent_team")
cli.py:454 rejects anything outside it, so research never reaches
inspect_runtime_config from the CLI. Both modes that do reach it declare the
web tools:
# apodex/profiles/react.yaml and agent_team.yaml
tools: [web_search, web_fetch, bash, grep_search, glob_search, read_file, todo_write]
I ran the preflight with a valid model config and an empty environment:
CLI-selectable modes: ['react', 'agent_team']
mode=react ok=True issues=[]
mode=agent_team ok=True issues=[]
mode=research ok=False issues=['missing_serper_api_key', 'missing_jina_api_key']
Impact
Someone following the README sets OPENAI_* and leaves SERPER_API_KEY blank,
since the README files it under "Optional web research tools". Preflight reports
nothing wrong. The first search then hands the model this:
[ERROR]: SERPER_API_KEY environment variable not set.
That goes into the transcript as a tool result, not to the user. The model reads
a failed call and keeps going from memory, so the run gets worse without saying
why. web_fetch does the same thing with JINA_API_KEY not set, though it at
least has a direct-fetch fallback.
Suggested fix
Check whether the active profile binds web_search and web_fetch instead of
comparing the mode name. profile.tools() already exposes that, and it stays
right if someone changes which tools a profile declares.
The current severity split still holds up. A missing SERPER_API_KEY should
block, a missing JINA_API_KEY should warn, since web_fetch degrades rather
than dying.
The README line could use a look too. With web_search bound in both shipped
modes, "optional" undersells it.
Summary
The runtime preflight only checks
SERPER_API_KEYandJINA_API_KEYwhen theactive mode is
research. The CLI won't let you pick that mode. It acceptsreactandagent_team, and both bindweb_searchandweb_fetch. So you canstart with no search key, see a clean preflight, and only find out when the
model gets an error string back from its first search.
Details
apodex/config.py:150:active_modeismode or profile.name, andcli.pypasses whichever mode theuser picked.
apodex/profiles/__init__.py:32caps that list:cli.py:454rejects anything outside it, soresearchnever reachesinspect_runtime_configfrom the CLI. Both modes that do reach it declare theweb tools:
I ran the preflight with a valid model config and an empty environment:
Impact
Someone following the README sets
OPENAI_*and leavesSERPER_API_KEYblank,since the README files it under "Optional web research tools". Preflight reports
nothing wrong. The first search then hands the model this:
That goes into the transcript as a tool result, not to the user. The model reads
a failed call and keeps going from memory, so the run gets worse without saying
why.
web_fetchdoes the same thing withJINA_API_KEY not set, though it atleast has a direct-fetch fallback.
Suggested fix
Check whether the active profile binds
web_searchandweb_fetchinstead ofcomparing the mode name.
profile.tools()already exposes that, and it staysright if someone changes which tools a profile declares.
The current severity split still holds up. A missing
SERPER_API_KEYshouldblock, a missing
JINA_API_KEYshould warn, sinceweb_fetchdegrades ratherthan dying.
The README line could use a look too. With
web_searchbound in both shippedmodes, "optional" undersells it.