mirror of
https://github.com/obra/superpowers.git
synced 2026-09-02 03:43:54 +00:00
fix(diagnosing-superpowers): human-prompt filters for injected lines and newer Codex rollouts
The Claude Code "human prompts" jq command counted harness-injected user-shaped lines as typed. On a real 9,170-line transcript it returned 374 rows, one of them a <task-notification> block. Excluding text that begins with <task-notification>, <command-name>, <local-command-stdout>, <system-reminder>, or "This session is being continued" brings that to 76, which matches the human-turn count a careful analyst arrives at by hand. The same transcript carries six human prompts that never appear as user lines at all: queued_command attachments with origin.kind "human", typed while a turn was already running. Adds a second command for those. Codex: on a thread_source "user" Codex Desktop rollout at cli_version 0.149.0-alpha.4.1 the user_message command returns nothing, and the prompts arrive as response_item messages with role "user". The file already documented that shape for subagent rollouts; it is now general, with the fallback jq and a note that the fallback also carries injected blocks (<subagent_notification>, <environment_context>, <skill>, <recommended_plugins>) that have to be skipped. Claude-Session: https://claude.ai/code/session_01DyaGKhTXvHNs2JgPhDktz7
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Codex session store
|
||||
|
||||
Verified against: Codex CLI 0.146.0 and 0.147.0 rollouts (`cli_version` in
|
||||
`session_meta`), macOS. When a field below is missing from the file in front
|
||||
of you, trust the file and say so in coverage notes.
|
||||
Verified against: Codex CLI 0.146.0, 0.147.0 and 0.149.0-alpha.4.1 rollouts
|
||||
(`cli_version` in `session_meta`), macOS. When a field below is missing from
|
||||
the file in front of you, trust the file and say so in coverage notes.
|
||||
|
||||
## Where
|
||||
|
||||
@@ -16,7 +16,10 @@ pointing at the parent thread id. Root sessions have `thread_source: "user"`.
|
||||
The most recently modified rollout whose `session_meta.payload.cwd` is the
|
||||
current working directory and whose `thread_source` is `user`. Confirm by
|
||||
matching the first `user_message` event to what your human partner
|
||||
remembers.
|
||||
remembers. Newer rollouts may carry no `user_message` event at all: when
|
||||
that command returns nothing, fall back to `response_item` messages with
|
||||
`role:"user"` (see Human-typed prompt below) and confirm against the first
|
||||
of those instead.
|
||||
|
||||
## Line types
|
||||
|
||||
@@ -28,7 +31,7 @@ Every line is `{timestamp, type, payload}` (some also carry `ordinal`).
|
||||
|---|---|
|
||||
| Session identity | `session_meta.payload`: `id`, `session_id`, `cwd`, `originator` (e.g. `Codex Desktop`), `cli_version`, `model_provider`, `thread_source`, `source`, `git` (`commit_hash`, `branch`, `repository_url`), `base_instructions.text`. |
|
||||
| Model per turn | `turn_context.payload`: `turn_id`, `model`, `effort`, `cwd`, `approval_policy`, `sandbox_policy`, `multi_agent_version`. Also `event_msg` `thread_settings_applied`. |
|
||||
| Human-typed prompt | `event_msg` with `payload.type=="user_message"`: `payload.message`. (`response_item` messages with `role:"developer"` are injected, not typed; see Subagents below for rollouts that carry no `user_message` event at all.) |
|
||||
| Human-typed prompt | `event_msg` with `payload.type=="user_message"`: `payload.message`. When that returns nothing — seen on `thread_source: "user"` Codex Desktop rollouts at `cli_version 0.149.0-alpha.4.1`, and on subagent rollouts — fall back to `response_item` messages with `payload.role=="user"`, text in `payload.content[0].text`. `role:"developer"` messages are injected boilerplate, not typed, and so is any fallback text that begins with a tag such as `<subagent_notification>`, `<environment_context>`, `<skill>` or `<recommended_plugins>`. On a subagent rollout the fallback text is the parent agent's dispatch prompt, not your human partner's. |
|
||||
| Assistant text | `event_msg` `agent_message` (`payload.message`, `payload.phase`) or `response_item` `message` with `role:"assistant"`. |
|
||||
| Tool calls | `response_item` with `payload.type` `function_call` (`name`, `arguments`, `call_id`) or `custom_tool_call` (`name`, `input`, `call_id`); outputs are `function_call_output` / `custom_tool_call_output` matched by `call_id`. Also `event_msg` `patch_apply_end` (`success`, `changes`), `web_search_end`, `mcp_tool_call_end` (`invocation.server`, `invocation.tool`). |
|
||||
| Turn timing | `event_msg` `task_started` (`turn_id`, `started_at`, `model_context_window`) and `task_complete` (`duration_ms`, `time_to_first_token_ms`, `last_agent_message`); `turn_aborted` (`reason`, `duration_ms`). |
|
||||
@@ -55,6 +58,8 @@ With `jq`:
|
||||
head -1 "$F" | jq '.payload | {id, cwd, originator, cli_version, model_provider, thread_source, git}' # identity
|
||||
jq -r '.type + "/" + (.payload.type // "")' "$F" | sort | uniq -c # census
|
||||
jq -r 'select(.type=="event_msg" and .payload.type=="user_message") | "\(input_line_number)\t\(.timestamp)\t\(.payload.message[0:160])"' "$F" # human prompts
|
||||
jq -r 'select(.type=="response_item" and .payload.type=="message" and .payload.role=="user")
|
||||
| "\(input_line_number)\t\(.timestamp)\t\((.payload.content[0].text // "")[0:160])"' "$F" # human prompts, fallback when the line above returns nothing; skip rows whose text starts with a `<tag>`
|
||||
jq -r 'select(.type=="turn_context") | "\(.timestamp)\t\(.payload.model)\t\(.payload.effort)"' "$F" # model per turn
|
||||
jq -c 'select(.type=="response_item" and (.payload.type=="function_call" or .payload.type=="custom_tool_call"))
|
||||
| {line:input_line_number, name:.payload.name, args:((.payload.arguments // .payload.input)|tostring|.[0:120])}' "$F" # tool calls
|
||||
|
||||
Reference in New Issue
Block a user