{"slug": "the-tokens-in-your-agent-harness", "title": "The tokens in your agent harness", "summary": "OpenAI's open-source Codex CLI spends extra tokens on hidden LLM calls, including an automatic thread-naming request capped at 960 bytes that runs whenever an unnamed thread receives a completed, nonempty user text message, according to an analysis of the Codex Rust source at version rust-v0.166.0. The naming call prefers the gpt-5.6-luna model at low reasoning effort when signed into ChatGPT and the model exists in the catalog, otherwise it uses the currently selected model, and returns a structured title preferably under five words or 36 characters. The analysis follows a report that Claude Code spends 15-20% of tokens updating a three-word status line, and notes Codex instead piggybacks its live activity indicator on reasoning summaries requested with standard responses rather than issuing a separate status-generation request.", "body_md": "# The Hidden Tokens In Your Agent Harness\n\nA look into how Codex spends your extra tokens.\n\n                        I was recently made aware of how\n                        \n                            [Claude Code spends 15-20% of the tokens on updating a three-word status line](https://gist.github.com/flamerix-ai/c3905705cc4205e5de3011fa2e74efce)\n                        \n                        . Since I work almost entirely within [Codex](https://github.com/openai/codex), I\n                        decided to take a peek at the code (Codex is open source and written in Rust). If you are\n                        working with an open source harness, be that Codex, pi, OpenCode, or something else, I encourage you\n                        to explore how it actually works.\n                    \n\n### Giving threads a name\n\n                        Whenever an unnamed thread receives a completed, nonempty user text message, an automatic \n                        thread naming procedure is invoked behind the scenes.\n                        \n<sup>[1](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/thread_routing.rs#L2070), \n                            [2](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/thread_title.rs#L180)</sup>\n                        This happens for example when you start a fresh Codex session and enter the first instructions\n                        into the text box. In this case the full prompt, including the title naming instructions,\n                        labels and user's text, are capped at 960 bytes and sent to an LLM.\n                        \n<sup>[3](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/thread_title.rs#L288), \n                            [4](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/thread_title.rs#L275)</sup>\n                        The returned response is a structured output, resulting in a thread title that is preferably\n                        under five words, or 36 characters. The preferred model is `gpt-5.6-luna` with low\n                        reasoning effort, when signed into ChatGPT and that model exists in the catalog; otherwise it\n                        uses the current selected model.\n                        \n<sup>[5](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/thread_title.rs#L32)</sup>\n\n                        You can also explicitly rename the thread by evoking `/rename <TITLE>` and\n                        this doesn't cost you anything. However, if you run `/rename` with no arguments,\n                        Codex immediately makes an LLM call requesting a title suggestion. That request uses up to\n                        eight recent substantive user/assistant messages, excluding assistant commentary.\n                        \n<sup>[6](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/chatwidget/interaction.rs#L476)</sup>\n\n### Knowing what's happening\n\n                        Next I took a look at the live activity indicator, to see if it's similar to how Claude Code\n                        does it. Turns out it's not. When using a model that supports it, which is any reasoning model,\n                        reasoning summaries are always requested along with the actual response.\n                        \n<sup>[7](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/core/src/client.rs#L998)</sup>\n                        So Codex piggy-backs the live activity indicator with standard requests. The TUI receives\n                        `ResoningSummaryTextDelta`, accumulates its text, extracts the latest usable line,\n                        and sets the status header; there is no separate status-generation request.\n                    \n\n                        Codex TUI has a catch-up recap feature that can be invoked explicitly via `/recap`,\n                        but is also automatically enabled by default via `tui.auto_recap = true`. Automatic\n                        recaps use the current model, together with the most recent visible changes and recap\n                        instructions, resulting in a structured `summary` and nullable\n                        `next_action` fields. The full recap prompt has a byte\n                        ceiling corresponding to 8 192 estimated tokens and the currently selected model is the one\n                        used for recap.\n                        \n<sup>[8](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/tui/src/app/recap.rs)</sup>\n\n### Remembering what matters\n\n                        Codex memories are persistent notes carried between sessions - useful knowledge, previous\n                        decisions, your stated or implied preferences. Memories can be enabled via\n                        `/memories` option. There are two background stages, and both make additional LLM\n                        requests.\n                    \n\n                        During the extraction stage the LLM processes an eligible past thread and records useful\n                        context, i.e. what you requested, findings, changes, corrections and unfinished work. The v2\n                        prompt explicitly tells is to preserve uncertainty and avoid turning a single task instruction\n                        into a general user preference.\n                        \n<sup>[9](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/memories/write/templates/memories/stage_one_system_v2.md)</sup>\n\n                        During the consolidation stage an internal agent combines those records into a compact index,\n                        updates preferences and project pointers, and removes unsupported or superseded claims.\n                        \n<sup>[10](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/memories/write/templates/memories/consolidation_v2.md)</sup>\n\n                        Extraction generally makes on request per selected thread; consolidation is an agent and can\n                        make several. By default `gpt-6-luna` is used for extraction and\n                        `gpt-6.1-terra` for consolidation, with configurable overrides. You can see your\n                        stored memories in `~/.codex/memories_v2/`.\n                    \n\n### Keeping watch\n\n                        Finally we have guardian tasks. Guardian is Codex's automatic security and permission reviewer.\n                        It evaluates whether an action could cause harm and whether the user authorised its target and\n                        side effects. It implements a background classifier, which Codex can launch when an eligible\n                        action starts, in order to determine whether the current workflow is high or low risk. It uses\n                        `gpt-5.6-luna` and is just a prompt\n                        \n<sup>[11](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/prompts/templates/guardian/classifier_instructions.md)</sup>\n                        that returns a high/low classification in the response, and converts the result into a score of\n                        1.0 or 0.0.\n                    \n\n                        Additionally there is a seperate internal agent turn that can hold execution while it evaluates\n                        the action about to be executed. For example, it makes a judgment whether the action could\n                        destroy data or disclose sensitive information, or whether it follows the necessary policies\n                        \n<sup>[12](https://github.com/openai/codex/blob/rust-v0.166.0/codex-rs/prompts/templates/guardian/policy_template.md)</sup>\n                        The result is a structured output with an allow/deny outcome, optionally with risk level,\n                        authorisation level and rationale. The reviewer can actually involve multiple LLM requests, as\n                        it reviews, inspects files, and reasons across these.\n                    \n\nI intentionally left out more explicit features, which include actual response handling (the thing that actually builds your code), as well as context compaction. Note that with compaction if you have background compaction enabled, compaction will start ahead of the foreground limit and generate candidates in parallel.\n\nUnderstanding where the tokens go is important both for better understanding of the billing and why you are hitting rate limits, but also in terms of being in control, wherever possible, of your agentic harness.", "url": "https://wpnews.pro/news/the-tokens-in-your-agent-harness", "canonical_source": "https://armincat.com/articles/where-tokens-go", "published_at": "2026-11-01 19:34:22+00:00", "updated_at": "2026-11-01 19:51:09.393472+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models"], "entities": ["OpenAI", "Codex", "Claude Code", "gpt-5.6-luna", "ChatGPT"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/the-tokens-in-your-agent-harness", "markdown": "https://wpnews.pro/news/the-tokens-in-your-agent-harness.md", "text": "https://wpnews.pro/news/the-tokens-in-your-agent-harness.txt", "jsonld": "https://wpnews.pro/news/the-tokens-in-your-agent-harness.jsonld"}}