Skip to content

Durable objective ​

The objective is the durable statement of what the session is trying to achieve. It survives turns, compaction, and resume, and it is separate from a goal: a goal is one attempt to advance the objective.

The objective feature and agent-driven mode changes are on by default. Turn them off with NEXGEN_EXPERIMENTAL_OBJECTIVE=0 and NEXGEN_EXPERIMENTAL_AGENT_MODES=0. The ModeControl tool, which lets the agent enter plan or swarm mode, also needs [modes] agent_control = true, which is the default.

What the objective is ​

An objective is one short piece of text with a monotonic revision number and its source (user or model). It has no terminal state: it is set, replaced, or cleared. Every change is written to the session wire, so it is reconstructed on resume.

When the objective changes, NexgenK publishes an objective.updated event on the session stream. That event is separate from goal.updated, so updating the objective never clears a goal or promotes a queued goal.

Enable the objective ​

Both flags are on by default. Set them to 0 to return to the previous behavior:

bash
NEXGEN_EXPERIMENTAL_OBJECTIVE=0 NEXGEN_EXPERIMENTAL_AGENT_MODES=0 nexgenk

With NEXGEN_EXPERIMENTAL_OBJECTIVE=0, the interface behaves as before: no objective is captured, no box appears, and the SetObjective and AskSuperUserQuestion tools are not registered. With [modes] agent_control = false, the agent cannot change modes by itself, and with [swarm] allow_agent_entry = false it cannot turn swarm mode on for a turn.

Capture objective blocks ​

A block wrapped in the configured marker is captured from the conversation:

text
<objetivo>
Redactar el informe trimestral y validarlo con finanzas.
</objetivo>

A block written by the user is applied immediately. A block written by the model becomes a proposal that you apply yourself, so the model cannot silently narrow the objective. The last block in a message wins. Inline mentions, code fences whose language is not text, and blocks larger than max_chars are ignored or rejected with a visible reason.

Configure the objective ​

All settings live in the [objective] section of config.toml:

toml
[objective]
markers = ["<objetivo>"]
max_chars = 2000
inject = "change"
max_goal_rewrites = 3
scan_max_chars = 32000
box = "auto"
superuser_timeout_ms = 120000
KeyDefaultEffect
markers["<objetivo>"]Text markers that delimit an objective block
max_chars2000Largest accepted objective; longer text is rejected, never truncated
inject"change"When to remind the agent: on each revision change, every turn ("turn"), or never ("off")
max_goal_rewrites3How many goals may be rewritten for the same objective revision
scan_max_chars32000Messages larger than this are not scanned for blocks
box"auto"Objective box visibility: "auto", "on", or "off"
superuser_timeout_ms120000Timeout for the AskSuperUserQuestion consultation

The objective box ​

When the objective is visible, the terminal UI shows a compact box above the editor. The collapsed line shows the revision and the start of the text, followed by ctrl+r. Press ctrl+r to expand or collapse it. The expanded box wraps the full text, keeps at most eight rows, and scrolls inside that body. The box is centered and never wider than 76 columns.

With box = "off" the box is hidden. With box = "auto" it appears when an objective exists; it collapses on very short terminals so an approval prompt and the editor still fit.

Objective, goals, and rewrites ​

The objective rules, and goals serve it:

  • A goal created for an objective records which revision it came from (derivedFrom and derivedFromRevision).
  • When the goal is blocked and the objective still stands, the agent rewrites the goal smaller instead of giving up.
  • The rewrite budget is max_goal_rewrites (3 by default). When it is exhausted, the agent stops rewriting and reports the blocker to you.
  • A new objective revision resets the rewrite budget.
  • The objective never completes on its own. Clear it or replace it when the work changes.

Recovery from failed turns ​

The main agent has no per-turn step cap, so a goal turn ends only when the agent stops working or the goal changes. If a turn fails for a reason that can change, the goal stays active and NexgenK schedules the next continuation automatically: 2 seconds later, then 10 seconds, 1 minute, 5 minutes, and every 30 minutes after that. A successful turn resets the sequence.

The recovery prompt tells the agent which error broke the previous turn and asks it to diagnose the failure instead of repeating the same action. After five consecutive recoveries the agent receives a reminder to change its approach or report the blocker instead of retrying forever.

Retrying cannot fix some failures, so those pause the goal instead: an invalid API key or permission error, a missing or invalid model configuration, a turn you cancelled, and a turn blocked by a UserPromptSubmit hook. In each case the pause reason in goal.updated names the cause, and /goal resume continues the work once you fix it.

Headless commands ​

In print mode, NexgenK interprets two commands without sending them to the model:

CommandEffect
/objective set <text>Applies the text as the current objective
/objective applyApplies the pending model proposal

In text output, the revision is reported once on stderr as Objective (revision N): .... In --output-format stream-json, each line is a JSON object; an objective change is a {"role":"meta","type":"objective.updated",...} line written after any open thinking block closes.

REST and SDK ​

The server exposes the durable objective on the session:

MethodPathPurpose
GET/api/v1/sessions/{session_id}/objectiveRead the record, including a pending proposal
PUT/api/v1/sessions/{session_id}/objectiveSet the objective from { "text": "..." }
DELETE/api/v1/sessions/{session_id}/objectiveClear the objective
POST/api/v1/sessions/{session_id}/objective/applyApply the pending proposal

The SDK exposes the same operations as session.getObjective(), session.setObjective(), session.clearObjective(), and session.applyObjective(). ResumedAgentState.objective carries the durable record even when the session has no goal.