Commit Graph
6 Commits
Author SHA1 Message Date
jifandGitHub 7db18c8241 fix: serialize goal progress accounting (#26155)
## Why

Goal progress accounting can be reached from multiple completion paths
for the same thread. Each path takes a progress snapshot, writes the
usage delta, and then marks that snapshot as accounted. When two
tool-completion hooks run at the same time, they can both observe the
same unaccounted delta and charge it twice.

## What changed

- Added a per-thread progress-accounting permit to
`GoalAccountingState`.
- Held that permit across the snapshot/write/mark-accounted critical
section for active-turn, idle, and tool-finish accounting.
- Added regression coverage for parallel tool-finish hooks so a shared
token delta is charged once and only one progress event is emitted.

## Testing

- Not run locally.
- Added `parallel_tool_finish_accounts_active_goal_progress_once`.
2026-06-03 15:10:16 +02:00
jif-oaiandGitHub c875bc8a33 Use templates for goal steering prompts (#25576)
## Why

Goal steering prompts have grown into long inline Rust strings, which
makes the authored prompt text hard to review and easy to damage while
changing the surrounding plumbing. Moving those prompts into embedded
Markdown templates keeps the policy text in the shape reviewers actually
read, while preserving the existing runtime substitution and objective
escaping behavior.

## What changed

- Added `ext/goal/templates/goals/continuation.md`, `budget_limit.md`,
and `objective_updated.md` for the three goal steering prompts.
- Updated `ext/goal/src/steering.rs` to parse those embedded templates
once with `codex-utils-template` and render the existing goal values
into them.
- Kept user objectives XML-escaped before rendering and converted budget
counters into template variables.
- Added the template directory to `ext/goal/BUILD.bazel` `compile_data`
so Bazel has the same embedded prompt inputs as Cargo.

## Testing

- Not run locally.
2026-06-01 10:55:14 +02:00
jif-oaiandGitHub 08504e86fb Add goal extension telemetry parity (#24615)
## Why

`core/src/goals.rs` already emits OTEL metrics for goal creation,
resume, terminal transitions, token counts, and duration. As `/goal`
moves into `ext/goal`, the extension needs to preserve that telemetry
contract instead of only emitting app-visible `ThreadGoalUpdated`
events.

This keeps the existing `codex.goal.*` metric surface intact while goal
lifecycle ownership shifts toward the extension.

## What changed

- Added an extension-local `GoalMetrics` helper that records the
existing `codex.goal.*` counters and histograms through `codex-otel`.
- Threaded an optional `MetricsClient` through `install_with_backend`,
`GoalExtension`, `GoalRuntimeHandle`, and `GoalToolExecutor`.
- Emitted created, resumed, and terminal goal metrics from the extension
paths that create goals, restore active goals on thread resume, account
budget limits, complete or block goals, and handle external goal
mutations.
- Updated existing goal extension test setup callsites to pass `None`
for metrics when instrumentation is not under test.

## Verification

Not run locally.
2026-05-26 19:48:32 +02:00
jif-oaiandGitHub 791b69dd53 [codex] Steer budget-limited goal extension turns (#23718)
## What
- Add a small extension capability for injecting model-visible response
items into the active turn
- Have the goal extension inject hidden goal-context steering when
tool-finish accounting reaches `BudgetLimited`
- Cover the extension backend path with an assertion on the injected
steering item

## Why
PR #23696 persists and emits the budget-limited goal update from
tool-finish accounting, but it leaves the model unaware of that
transition. The existing core runtime steers the model to wrap up in
this case; the extension path should do the same through an explicit
host capability.

## Testing
- `just fmt`
- `cargo test -p codex-goal-extension`
- `cargo test -p codex-extension-api`
2026-05-21 12:54:00 +02:00
jif-oaiandGitHub b555dd5d1d feat: wire goal extension tools to the dedicated goal store (#23685)
## Why

`ext/goal` already had the tool specs and contributor wiring for
`/goal`, but the installed tools still depended on a placeholder backend
that always errored. That meant the extension could not actually own
goal persistence even though the dedicated `thread_goals` store already
exists.

This change wires the extension tools directly to the dedicated goal
store so the extension can create, read, and complete goals against real
state instead of falling back to host-side placeholders.

## What changed

- make `install_with_backend(...)` require
`Arc<codex_state::StateRuntime>` so goal storage is always available
when the extension is installed
- remove the unused no-backend/public backend abstraction from
`ext/goal` and have the tool executors talk directly to `StateRuntime`
- map `thread_goals` rows into the existing protocol response shape for
`get_goal`, `create_goal`, and `update_goal`
- preserve current thread-list behavior by filling an empty thread
preview from the goal objective when a goal is created through the
extension path
- add integration coverage for the installed tool surface, including
successful goal creation and duplicate-create rejection

## Testing

- `cargo test -p codex-goal-extension`
2026-05-20 14:44:17 +02:00
jif-oaiandGitHub a80f07ec4a chore: goal ext skeleton (#23288)
Skeleton of `/goal` in extension
Lot's of follow-ups coming
2026-05-18 13:32:21 +02:00