本文分析的是 Hermes Agent 最近一个 release:v2026.4.8(发布于 2026-04-08)。
- Release 页面:https://github.com/NousResearch/hermes-agent/releases/tag/v2026.4.8
- 对应发布提交:
86960cdbb0148145890e2ee90b4e157fa899f6e1 - 本文里所有 GitHub 代码链接都尽量使用这个 commit hash 做 permanent link,避免后续
main变化导致失真。
我会先讲整体架构,再重点展开 OpenAI 相关处理:
- 怎么把 OpenAI / Codex 接进来
- 登录流程怎么跑
- refresh token 怎么转
- prompt 层做了哪些“专门为 GPT / Codex 调过”的处理
- 这些设计为什么合理,以及它们的 trade-off
Hermes Agent 本质上是一个“统一 OpenAI 风格接口 + 多 provider 适配层 + 工具执行循环 + 多入口 UI”的 agent runtime。
它不是把每个 provider 当成完全独立系统来写,而是做了三层抽象:
- 上层:CLI / Gateway / Cron / ACP 等入口
- 中层:
AIAgent驱动的统一对话与工具循环 - 下层:provider/runtime/auth adapter,把 OpenAI、OpenRouter、Anthropic、Nous、Codex、Copilot 等都压到相对统一的调用模型上
这也是它能同时支持:
- CLI
- Telegram / Discord / Slack / Signal / Matrix 等 gateway
- Cron job
- Subagent delegation
- MCP / terminal / browser / file / memory 等工具
的关键原因:上层入口不同,但中层 agent loop 基本是同一个。
+-------------------------------------------------------------+
| User Interfaces |
|-------------------------------------------------------------|
| CLI (cli.py) | Gateway (gateway/run.py) | Cron | ACP | API |
+-----------------------------+-------------------------------+
|
v
+-------------------------------------------------------------+
| AIAgent (run_agent.py) |
|-------------------------------------------------------------|
| - build system prompt |
| - manage conversation state |
| - choose api_mode / provider |
| - send request to model |
| - parse tool calls / responses |
| - retry / recovery / fallback |
+-----------------------------+-------------------------------+
|
v
+-------------------------------------------------------------+
| Provider / Runtime Resolution |
|-------------------------------------------------------------|
| hermes_cli/runtime_provider.py |
| hermes_cli/providers.py |
| hermes_cli/auth.py |
| agent/auxiliary_client.py |
+-------------------+-------------------+---------------------+
| | |
v v v
+----------------+ +----------------+ +------------------+
| OpenRouter | | Anthropic | | OpenAI Codex |
| chat API | | Messages API | | Responses-style |
+----------------+ +----------------+ +------------------+
| | |
+---------+---------+---------------------+
|
v
+-------------------------------------------------------------+
| Tool Runtime Layer |
|-------------------------------------------------------------|
| terminal | file tools | browser | execute_code | delegate |
| memory | session_search | skill tools | cron | MCP |
+-------------------------------------------------------------+
如果再压缩成一句话:
Hermes 的核心不是“某个模型”,而是 AIAgent + provider adapter + tool loop 这三个东西的组合。
CLI、Telegram、Discord 这些入口的职责,主要是:
- 收用户输入
- 做平台特定交互(例如 Telegram 命令、Slack thread、approval button)
- 准备当前 session 的 provider / model / callbacks
- 把任务交给
AIAgent
在代码结构上,这个分层非常明显:
- CLI 主 orchestrator:
cli.py - Gateway 主入口:
gateway/run.py - 真实 agent loop:
run_agent.py
所以 Hermes 的“产品表面”很多,但“内核”相对集中。
AIAgent 的初始化里就已经把几个关键决策做掉了:
- 当前模型是什么
- 当前 provider 是什么
- 当前 base URL 是什么
- 当前 API 模式是:
chat_completionscodex_responsesanthropic_messages
关键代码:
run_agent.py中AIAgent.__init__的 provider / api_mode 判定- Permanent link: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L553-L581
这里最值得注意的点是:
- 如果 provider 明确是
openai-codex,直接走codex_responses - 如果 base URL 看起来像
chatgpt.com/backend-api/codex,也会自动判成codex_responses - 更激进的一点:如果是“direct OpenAI URL”,即使原本是
chat_completions,也会被切到codex_responses
这段逻辑说明 Hermes 在 v2026.4.8 的判断是:
“对于 OpenAI 新一代 GPT / Codex,工具型 agent 默认更适合 Responses 路线,而不是老式 chat completions。”
这不是表面兼容,而是产品层面的立场。
Hermes 的内部消息表示尽量统一。真正到 API 边界时,再做 provider-specific 转换。
最典型的是 system role -> developer role 的延迟转换:
- 内部一直保留
system - 只有在
_build_api_kwargs()里,如果模型命中DEVELOPER_ROLE_MODELS(例如gpt-5/codex),才把第一条 system message 改成 developer
关键代码:
agent/prompt_builder.py定义DEVELOPER_ROLE_MODELS = ("gpt-5", "codex")https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/prompt_builder.py#L278-L283run_agent.pyAPI 边界转换 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L5340-L5351
这个设计很干净:
- 内部状态不被 provider 污染
- 外部请求最大化贴合 provider 最佳实践
Hermes 的 prompt 不是单纯一块字符串,而是多个来源拼接:
- 默认 agent identity
- memory / user profile block
- skill system prompt
- context files(SOUL.md / AGENTS.md / 其他上下文)
- model-specific guidance
- API-call-time 的 ephemeral system prompt
关键 system prompt 组装逻辑在:
run_agent.py::_build_system_prompt()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L2625-L2656
真正发请求前,又会额外做一次 API-call-time 拼接:
- 把
ephemeral_system_prompt只在这次请求里拼上 - 再插入 prefill messages
- 再按 provider 特性做缓存或清洗
关键代码:
run_agent.pyAPI 发送前的消息构造 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7217-L7249
我觉得这是 Hermes 很成熟的一点:
它明确区分了两类 prompt:
- 持久 prompt(应该进入 session / cache / trajectory)
- 临时 prompt(只影响当前 API call,不污染长期状态)
这对 agent 系统非常重要。否则很多临时策略会污染后续回合,最后 prompt 越堆越脏。
这一版里,OpenAI 相关处理分成两类:
比如:
- 自定义
OPENAI_BASE_URL - 一些 OpenAI-compatible 服务
- 某些聚合器的 OpenAI 风格接口
它们会走统一的 OpenAI client 路线。
这条路线不只是一个 API key,而是一整套:
- provider overlay
- OAuth 登录
- access token / refresh token 管理
- runtime credential resolution
- Responses API / Codex backend 适配
- 模型列表发现
Hermes 专门把它抽成了 openai-codex provider。
关键 provider overlay:
hermes_cli/providers.pyhttps://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/providers.py#L56-L60
这里明确写了:
- transport =
codex_responses - auth_type =
oauth_external - base_url_override =
https://chatgpt.com/backend-api/codex
也就是说,在 Hermes 看来,OpenAI Codex 不是普通 openai_chat,而是一个 transport 不同、auth 也不同的 provider。
这点很关键。
当用户选中 openai-codex,runtime provider 会把它解析成:
- provider =
openai-codex - api_mode =
codex_responses - base_url =
https://chatgpt.com/backend-api/codex(或 override) - api_key = 通过
resolve_codex_runtime_credentials()取到的 access token
关键代码:
hermes_cli/runtime_provider.pyhttps://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/runtime_provider.py#L482-L499
这一步的意义是:
上层根本不用知道 “OpenAI Codex token 怎么来的”。 它只需要拿到一组已经可以跑的 runtime credentials。
如果没有显式传 API key / base_url,AIAgent 会走统一 provider router:
resolve_provider_client(self.provider or "auto", model=self.model, raw_codex=True)
关键代码:
这段值得注意的地方有两个:
-
raw_codex=True- 表示主 agent loop 需要直接接触 Codex Responses 风格 client
- 不是只拿一个抽象过的 chat client
-
如果用户明确选了某个非 OpenRouter provider,但没凭证,Hermes 会 fail fast
- 不会偷偷回退到 OpenRouter
- 这避免“用户明明以为自己在用 Codex,实际上却跑到别家 provider 去了”
这类 fail-fast 行为在 agent 产品里很重要,因为 provider 切错,语义、费用、工具行为都可能变。
这是你特别关心的部分。
Hermes 在 v2026.4.8 对 OpenAI 的“官方”接入重点,并不是传统 OPENAI_API_KEY,而是 openai-codex 这条 OAuth 流程。
用户走 hermes model 或 hermes auth 时,如果选了 OpenAI Codex,会进入 _login_openai_codex()。
关键代码:
hermes_cli/main.py选择 provider 后进入 Codex model flow https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/main.py#L1040-L1045hermes_cli/auth.py::_login_openai_codex()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L2466-L2528
_login_openai_codex() 不是无脑重新登录,它先做三层检查:
- 先看 Hermes 自己 auth store 里有没有可用凭证
- 再看
~/.codex/auth.json里有没有 Codex CLI 的凭证可导入 - 都没有,再跑 fresh device code flow
这是很实用的工程设计,因为它同时兼顾:
- 首次登录用户
- 已登录过 Hermes 的用户
- 先用过 Codex CLI,后来想接 Hermes 的用户
真正的 OAuth 设备码流程在 _codex_device_code_login()。
关键代码:
hermes_cli/auth.py::_codex_device_code_login()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L2531-L2665
它的步骤很标准:
向:
https://auth.openai.com/api/accounts/deviceauth/usercode
发请求,拿:
user_codedevice_auth_idinterval
终端里提示用户去:
https://auth.openai.com/codex/device
输入 user_code。
向:
https://auth.openai.com/api/accounts/deviceauth/token
轮询,直到拿到:
authorization_codecode_verifier
最后向 CODEX_OAUTH_TOKEN_URL 做 authorization code exchange,拿到:
access_tokenrefresh_token
这一版有个非常明确的设计取舍:
Hermes 会读取 / 导入 ~/.codex/auth.json,但不会把它当长期唯一真相源。
它会把凭证保存进 Hermes 自己的 auth store。
代码里写得很直白:
- tokens stored in
~/.hermes/auth.json - 不再直接写回
~/.codex/
关键代码:
hermes_cli/auth.py::_login_openai_codex()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L2519-L2528hermes_cli/auth.py::_read_codex_tokens()/_save_codex_tokens()/ resolve flow https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L966-L1025
这是对的,因为 Codex CLI / VS Code 插件 / Hermes 如果共用一个 refresh token,会互相踩。
这一块其实是 v2026.4.8 对 OpenAI 处理最“像产品工程”的部分。
核心刷新函数在:
hermes_cli/auth.py::refresh_codex_oauth_pure()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L1029-L1116
它做的事很直接:
- 用
refresh_token调CODEX_OAUTH_TOKEN_URL grant_type=refresh_token- 带上
client_id - 成功后拿新的
access_token - 如果返回了新的
refresh_token,就旋转过去
这里有两个关键点:
-
函数名叫
pure- 意味着它本身不直接改全局 auth state
- 只是返回刷新结果
- 真正落盘由外层控制
-
它显式处理
refresh_token_reused- 这是 Codex / ChatGPT OAuth 场景里很现实的问题
- 如果另一个客户端消费掉了 refresh token,这里会直接报需要重新登录
resolve_codex_runtime_credentials() 会在 access token 即将过期时自动刷新。
关键代码:
hermes_cli/auth.py::resolve_codex_runtime_credentials()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L1174-L1232
这里的流程是:
- 先读 Hermes 自己 auth store
- 如果完全没有,再尝试从
~/.codex/auth.json迁移 - 检查 access token 是否快过期
- 如果快过期,在锁里重读并刷新
- 返回 runtime 可用的:
- provider
- base_url
- api_key(其实是 access token)
- last_refresh
这里的锁也很关键:
它不是简单刷新,而是“在锁里重读再刷新”,避免多个 Hermes 进程并发刷新同一份 token。
如果启用了 credential pool,Hermes 还会处理一个更麻烦的现实问题:
“另一个客户端刷新了 token,导致当前 pool 里的 refresh token 过期。”
为此它加了 _sync_codex_entry_from_cli():
- 比较 pool entry 里的 refresh token 和
~/.codex/auth.json的 refresh token - 不一致就把最新那对 token 同步回来
关键代码:
agent/credential_pool.py::_sync_codex_entry_from_cli()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/credential_pool.py#L447-L475
同时 _refresh_entry() 对 openai-codex 分支也会用 refresh_codex_oauth_pure() 刷新并旋转 refresh token:
agent/credential_pool.py::_refresh_entry()https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/credential_pool.py#L480-L523
这个设计很实用:
Hermes 已经接受了一个现实——OpenAI Codex OAuth token 并不是“单机单进程永远自洽”的,外部客户端会参与状态变化。
所以它没有假设“自己的 token store 永远是唯一真相”,而是加了同步与迁移逻辑。
这是成熟系统才会做的事。
即使前面都做了刷新,真正发请求时如果拿到 401,Hermes 还是会再尝试一次 Codex auth refresh,然后重试请求。
关键代码:
run_agent.py401 后尝试_try_refresh_codex_client_credentials(force=True)https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7840-L7846
这说明它把 token 失效处理成三层防线:
- 进入 runtime 前预刷新
- credential pool 内刷新 / 同步
- 请求 401 后最后一次即时刷新
这套链路挺扎实。
如果用户进入 OpenAI Codex 的 model selection,Hermes 会:
- 确保已经登录
- 拿到当前可用 token
- 通过
get_codex_model_ids()获取模型列表
关键代码:
hermes_cli/main.pymodel flow https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/main.py#L1333-L1356
模型拉取逻辑在:
hermes_cli/codex_models.pyhttps://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/codex_models.py#L55-L90
它会请求:
https://chatgpt.com/backend-api/codex/models?client_version=1.0.0
然后过滤:
supported_in_api == False的模型- visibility 为 hidden 的模型
- 再按 priority 排序
更有意思的是,它还会加一层“synthetic forward-compat models”,例如:
- 如果旧模板模型存在,也能把某些新 slug 补出来
这说明作者不想把模型目录完全交给服务端即时返回,而是希望 UI 在模型升级过渡期也尽量稳。
这是另一个重点。
我觉得 v2026.4.8 的一个明显特征是:
它不再把 GPT / Codex 当作“和别的模型一样只是换个 provider”,而是专门给它们写了行为矫正 prompt。
agent/prompt_builder.py 里有一个很显眼的常量:
OPENAI_MODEL_EXECUTION_GUIDANCE
关键代码:
- 定义位置 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/prompt_builder.py#L192-L253
- 注入位置 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L2647-L2656
这个 guidance 不是泛泛而谈,而是明显针对 GPT / Codex 常见 failure mode:
- 工具调用半途而废
- 缺前置检查
- 不验证结果就宣称完成
- 缺上下文时靠猜
- 本来该调用工具却直接用语言糊过去
它里面甚至把规则写成半结构化块:
<tool_persistence><mandatory_tool_use><act_dont_ask><prerequisite_checks><verification><missing_context>
这其实很像“给模型上操作系统纪律”。
原因很简单:
GPT / Codex 类模型往往不是不会用工具,而是:
- 容易过早收敛
- 容易把“计划”说成“已完成”
- 容易在信息缺失时做语言补完
Hermes 这里的做法,不是改 decoder,而是把 agent 成功所需的执行纪律直接前置进 prompt。
这是一种很现实、也很有效的工程策略。
前面提过,这版对 GPT-5 / Codex 还专门做了 developer role 转换。
关键代码:
agent/prompt_builder.py中的DEVELOPER_ROLE_MODELShttps://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/prompt_builder.py#L278-L283run_agent.py::_build_api_kwargs()中真正替换 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L5340-L5351
这是一个很细,但很值钱的兼容层:
内部依然统一用 system role,只有对 OpenAI 新模型出站时才变成 developer role。
这避免 Hermes 内部逻辑到处都要分叉。
严格说,prompt caching 的主优化对象在这版更多是 Claude / Anthropic 路线,而不是 OpenAI。
但对 OpenAI 一样有两个重要处理:
ephemeral_system_prompt不进入持久 system prompt- plugin / 外部 recall 等动态信息尽量不污染稳定 cache prefix
关键代码:
run_agent.py中系统 prompt 的 API-call-time 注入 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7217-L7229
这对 OpenAI 的实际意义是:
即使没有 Anthropic 式 cache_control,Hermes 也在努力保持 prompt 结构稳定,减少“临时上下文把主指令结构搞脏”的问题。
Codex Responses 路线和普通 chat completion 路线在 tool call 字段上并不完全一样。
Hermes 会保留一些 Codex 专用字段(如 call_id, response_item_id)用于内部兼容,但对严格 provider 又会清洗掉它们。
关键代码:
run_agent.py消息清洗与严格 API 适配 https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7207-L7213
这再次体现了 Hermes 的总体策略:
内部表示 richer,出站 payload provider-specific。
我觉得这是这一版最值得强调的架构判断之一。
在 AIAgent.__init__() 里,Hermes 明确写了:
- Direct OpenAI sessions use the Responses API path
- GPT-5.x tool calls with reasoning are rejected on
/v1/chat/completions - Hermes is a tool-using client by default
关键代码:
这句话其实已经说明了他们的产品判断:
Hermes 不是一个“纯聊天壳”,而是一个默认 heavily tool-using 的 agent。
既然如此,就应该优先走更适合 reasoning + tool use 的 transport,而不是为了 API 兼容保守地死守 chat completions。
这是对 agent 产品定位非常清楚的体现。
很多项目接 OpenAI,只做:
- base_url
- api_key
- chat.completions.create()
Hermes 这版显然已经超过这个层次。它考虑的是:
- provider overlay
- runtime credential resolution
- OAuth 生命周期
- token rotation
- model catalog discovery
- tool/reasoning transport 匹配
- prompt 行为矫正
这是 agent 产品应有的深度。
这点非常关键。
只要系统和 Codex CLI / VS Code / 其他 profile 共存,就迟早会撞上 refresh token rotation 问题。
Hermes 没回避这个问题,而是:
- 单独 auth store
- import 但不共用
- refresh 失败时给出明确错误
- pool 里再同步一次
这套设计说明作者确实踩过坑。
很多 agent 框架的毛病是“同一套 system prompt 喂所有模型”。
Hermes v2026.4.8 明显不这么想。
它承认不同模型家族有不同 failure mode,于是:
- Google 系模型加一套
- GPT / Codex 加一套
- developer role 再额外适配
这是更务实的路线。
一旦你支持:
- OpenAI-compatible endpoint
- ChatGPT / Codex OAuth
- direct OpenAI URL -> Responses 自动切换
- credential pool + token sync
代码复杂度肯定上来。
Hermes 的做法是把复杂度主要集中在:
hermes_cli/auth.pyhermes_cli/runtime_provider.pyrun_agent.pyagent/auxiliary_client.py
这算是“集中复杂”,还可以接受。
如果以后继续扩张,OpenAI 相关逻辑会分散在:
- auth
- provider overlay
- runtime resolution
- auxiliary client
- main agent loop
- prompt builder
这对维护者是个挑战。
如果我来继续演进,我会考虑再抽一层更明确的 openai_runtime.py / codex_runtime.py,把现在散落的 Codex transport 规则再聚一聚。
但以 v2026.4.8 的状态来说,它已经比很多 agent 项目整洁了。
如果只看最近这个 release,我对 Hermes Agent 的判断是:
它已经不是一个“把 LLM API 套在工具调用上”的简单 agent 了,而是在往“多 provider、多 auth 形态、多 transport 的统一 agent runtime”演化。
而 OpenAI 这条线,恰好最能体现它的架构成熟度。
因为在 OpenAI 这里,Hermes 不只是做了:
- 接 model
- 发请求
而是把完整链路都打通了:
- provider overlay
- runtime credential resolution
- device code login
- auth store 隔离
- refresh token rotation
- 401 后再刷新
- Codex model discovery
- GPT / Codex prompt discipline
- developer role 边界转换
- Responses transport 默认化
如果你要我用一句中文概括它对 OpenAI 的处理:
“这版 Hermes 不是把 OpenAI 当成一个 endpoint,而是把它当成一个有自己认证生命周期、传输语义和行为偏差的 agent substrate 来认真适配。”
这是我觉得最值钱的地方。
- Release 页面: https://github.com/NousResearch/hermes-agent/releases/tag/v2026.4.8
- Release commit: https://github.com/NousResearch/hermes-agent/commit/86960cdbb0148145890e2ee90b4e157fa899f6e1
AIAgent初始化 / api_mode 判断: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L553-L581- system prompt 注入 OpenAI/GPT/Codex guidance: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L2625-L2656
- developer role 边界转换: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L5340-L5351
- API call 前 system/prefill/cache/message sanitize: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7217-L7249
- provider overlay: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/providers.py#L56-L60
- runtime provider 解析
openai-codex: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/runtime_provider.py#L482-L499 - agent 初始化时从 provider router 取 client: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L760-L817
- OpenAI Codex 登录入口: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L2466-L2528
- device code 登录流程: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L2531-L2665
- refresh token 逻辑: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L1029-L1116
- runtime credential resolve + 自动刷新: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/auth.py#L1174-L1232
- credential pool 中 Codex token sync / refresh: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/credential_pool.py#L447-L523
- 401 后强制刷新再重试: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/run_agent.py#L7840-L7846
- GPT / Codex execution guidance 定义: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/prompt_builder.py#L192-L253
- developer role model 列表: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/agent/prompt_builder.py#L278-L283
- Codex 模型拉取与排序: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/codex_models.py#L55-L90
hermes model中的 Codex model flow: https://github.com/NousResearch/hermes-agent/blob/86960cdbb0148145890e2ee90b4e157fa899f6e1/hermes_cli/main.py#L1333-L1356