Skip to content

feat: add core session goals#87469

Merged
steipete merged 18 commits into
mainfrom
core-thread-goals
May 29, 2026
Merged

feat: add core session goals#87469
steipete merged 18 commits into
mainfrom
core-thread-goals

Conversation

@steipete

@steipete steipete commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces Add /goal session continuation command #85723 with core-owned session goals instead of a plugin/lease extension surface.
  • Persists goals on SessionEntry, exposes get_goal/create_goal/update_goal model tools, and adds native/text /goal controls.
  • Adds resumable blocked/budget-limited goal behavior, projected session-row goal state, and a compact TUI footer goal indicator.
  • Adds a dedicated Goal docs page plus TUI/slash-command cross-links and focused regression coverage.

Verification

Behavior addressed: Core-owned thread/session goals with model tools, /goal controls, TUI footer status, and dedicated docs, replacing plugin-owned PR #85723.

Real environment tested: Local OpenClaw checkout.

Exact steps or command run after this patch:

  • pnpm exec oxfmt --check ... on touched TS/docs files
  • node scripts/run-oxlint.mjs ... on touched TS files
  • pnpm docs:list
  • pnpm docs:check-mdx
  • pnpm format:docs:check
  • pnpm docs:check-links -- docs/tools/goal.md docs/tools/slash-commands.md docs/web/tui.md docs/cli/tui.md docs/tools/index.md
  • git diff --check
  • pnpm exec tsx -e ... direct goal lifecycle, formatter, stale-baseline, budget-resume, and TUI session-refresh smokes
  • /Users/steipete/Projects/agent-skills/skills/autoreview/scripts/autoreview --mode local

Evidence after fix: Formatting, oxlint, docs index, docs MDX, docs formatting, docs links, whitespace, direct TS smokes, and final local autoreview passed. Final autoreview reported no accepted/actionable findings.

Observed result after fix: Goals persist in core session state; model tools can read/create/complete/block goals; /goal can start, show, pause, resume, complete, block, and clear goals; blocked goals can be resumed; budget-limited goals resume with a fresh budget window; stale token baselines are not overcounted; TUI session rows carry goal state and the footer shows compact goal status.

What was not tested: Vitest wrapper did not complete in this checkout; it hung without test output and was stopped. Earlier broad tsgo was blocked on existing unrelated src/config/io.ts unique-symbol errors.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation agents Agent runtime and tooling size: L maintainer Maintainer-authored PR labels May 28, 2026
@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed May 29, 2026, 4:24 PM ET / 20:24 UTC.

Summary
The PR adds core-owned durable session goals across session storage, model tools, slash commands, Gateway/TUI/Web UI surfaces, Telegram transcript scoping, docs, and regression tests.

Reproducibility: yes. Source inspection gives a high-confidence path: selected-global local runs store agentId but emit unscoped global events that the new TUI filter rejects, and update_goal writes can be overwritten by later stale session-entry persistence.

Review metrics: 1 noteworthy metric.

  • Core goal contract surface: 1 durable SessionEntry field and 3 model tools added. This creates new persistent and model-facing behavior that maintainers should explicitly accept before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🧂 unranked krab
Result: blocked by patch quality or review findings.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Propagate agentId on all local global chat, abort/error/final, and BTW event payloads and add a focused non-default local TUI test.
  • [P2] Refresh or protect live session goal state after model tool updates so later turn persistence cannot overwrite complete or blocked.
  • Rerun the focused changed-surface tests and structured review after the fixes.

Risk before merge

  • [P1] Merging as-is can make openclaw tui --local selected-global non-default agent runs execute while dropping visible chat final/delta/abort/BTW events in the TUI.
  • [P1] Merging as-is can lose model-driven goal completion or blocking because later turn persistence can reapply stale goal state over the store update.
  • [P1] The PR introduces a durable core SessionEntry.goal contract plus new model-facing tools, so maintainers need to explicitly accept that core-owned product/API direction before landing.

Maintainer options:

  1. Fix the blockers before merge (recommended)
    Propagate agentId on local global event payloads and protect live goal updates from stale turn persistence before re-reviewing the same broad feature branch.
  2. Accept the new core contract explicitly
    Maintainers can still choose to own core durable goals and the new model tools, but that decision should be visible before the branch lands.
  3. Pause if core ownership is not settled
    If core-owned session goals are not the desired product direction, pause this branch and reopen the narrower plugin/API design discussion instead of landing partial infrastructure.

Next step before merge

  • [P2] Needs author fixes for two concrete blockers plus maintainer acceptance of the new core session-goal contract; the protected maintainer label also requires human handling.

Security
Cleared: No concrete security or supply-chain regression was found; the diff does not add dependencies, lockfile changes, workflows, secret handling, or downloaded code execution paths.

Review findings

  • [P1] Propagate agentId on local global events — src/tui/embedded-backend.ts:354
  • [P1] Keep goal updates out of stale turn persistence — src/agents/tools/goal-tools.ts:131-136
Review details

Best possible solution:

Land only after local selected-global events carry agentId, goal tool writes are reconciled with the live session entry or later persistence omits stale goal fields, and maintainers accept core-owned session goals as the canonical contract.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection gives a high-confidence path: selected-global local runs store agentId but emit unscoped global events that the new TUI filter rejects, and update_goal writes can be overwritten by later stale session-entry persistence.

Is this the best way to solve the issue?

No. The core goal design may be acceptable, but the current branch needs the local event scope and live goal-state persistence fixes before it is the narrow maintainable solution.

Full review comments:

  • [P1] Propagate agentId on local global events — src/tui/embedded-backend.ts:354
    sendChat now records the selected agentId on each local run, but the local chat and chat.side_result emitters still publish only sessionKey: "global". The new TUI filter rejects global events without agentId when the selected agent is not the default, so openclaw tui --local, /agent work, then a global send or /btw can execute while dropping visible delta/final/abort/BTW output. Include agentId: run.agentId on those local event payloads and cover the non-default selected-global path.
    Confidence: 0.95
  • [P1] Keep goal updates out of stale turn persistence — src/agents/tools/goal-tools.ts:131-136
    update_goal writes the completed/blocked status directly to the session store, but the agent turn still holds the older sessionStore[sessionKey] working copy. Later run persistence merges that stale entry back with normal spread semantics and can overwrite goal, so model-driven completion/blocking can be lost before the run finishes. Refresh the live session entry after the tool write or make later persistence omit stale goal fields.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against eb7e237151e7.

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦞 diamond lobster and patch quality is 🧂 unranked krab.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: This is a broad user-facing feature with session, agent, Gateway, Telegram, TUI, Web UI, and docs impact, but it is not an emergency regression.
  • merge-risk: 🚨 compatibility: The PR adds a durable core session-goal slot and new model-facing tools, changing core behavior and API expectations for existing sessions and clients.
  • merge-risk: 🚨 session-state: A stale in-memory session entry can overwrite a model-driven goal status update during later turn persistence.
  • merge-risk: 🚨 message-delivery: Selected-global local TUI runs can emit unscoped global events that the new TUI filter drops for non-default agents.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦞 diamond lobster and patch quality is 🧂 unranked krab.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (recording): The PR includes local/Testbox validation plus Mantis Telegram Desktop before/after video proof for visible /goal replies; it is sufficient real behavior proof, though it does not cover the two blockers above.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR includes local/Testbox validation plus Mantis Telegram Desktop before/after video proof for visible /goal replies; it is sufficient real behavior proof, though it does not cover the two blockers above.
  • proof: 🎥 video: Contributor real behavior proof includes video or recording evidence. The PR includes local/Testbox validation plus Mantis Telegram Desktop before/after video proof for visible /goal replies; it is sufficient real behavior proof, though it does not cover the two blockers above.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. The PR changes visible Telegram /goal replies, and the existing Mantis Telegram Desktop proof is the right proof lane for that behavior.
Evidence reviewed

What I checked:

  • Repository policy read: Root AGENTS.md plus scoped guides for docs, agents, agent tools, gateway, gateway server methods, TUI, and UI were read and applied; the policy treats plugin APIs, session state, provider routing, config/defaults, and channel delivery as compatibility-sensitive review surfaces. (AGENTS.md:15, eb7e237151e7)
  • Latest PR head inspected: Local git contains the PR head commit 6006871d80f917d509ec9e2f74f0fd8f606c9c79, whose latest commit only changes selected-global web subscription handling; it is not contained in local release tags or branches. (6006871d80f9)
  • PR diff surface: The branch changes 135 files with 10,368 additions and 478 deletions, including core session storage, Gateway protocol/server methods, TUI, Web UI, Telegram transcript routing, docs, and tests. (6006871d80f9)
  • Local TUI selected-global event bug: The PR stores agentId on LocalRunState, but local chat and BTW emitters still send only sessionKey; the new TUI global-agent filter rejects unscoped global events for non-default selected agents. (src/tui/embedded-backend.ts:354, 6006871d80f9)
  • Goal update overwrite bug: update_goal writes to the session store directly, while later turn persistence still merges the in-memory session entry with ordinary spread semantics, so a stale goal field can overwrite the model's completed or blocked status. (src/agents/tools/goal-tools.ts:131, 6006871d80f9)
  • Real behavior proof: The PR body and follow-up comment provide local focused validation, a Blacksmith Testbox run tbx_01kstmf0j5cspsk98vd7tq9yx6 passing 766 tests, and Mantis Telegram Desktop before/after video proof for /goal replies; one inspected candidate frame shows Telegram /goal commands and replies. (6006871d80f9)

Likely related people:

  • steipete: Peter Steinberger authored the PR stack and also appears in current-main blame/log history for the session/global scoping and session merge surfaces used by this review. (role: feature author and recent area contributor; confidence: high; commits: 6006871d80f9, d18375ef75f9, e3be541a6c2a; files: src/tui/embedded-backend.ts, src/tui/tui-event-handlers.ts, src/agents/tools/goal-tools.ts)
  • Josh Lehman: Recent history shows prior work on scoping session create aliases to the requested agent, which is adjacent to the selected-global agent scoping affected here. (role: adjacent session-scoping contributor; confidence: medium; commits: 1c83e2eec727; files: src/gateway/server-methods/sessions.ts)
  • Onur Solmaz: Recent history shows thread-bound agent and subagent session work in related session-routing areas; this is useful routing context but less directly tied to the new goal implementation. (role: adjacent session/threading contributor; confidence: low; commits: a7d56e3554d0, 8178ea472db1; files: src/gateway/server-methods/sessions.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@blacksmith-sh

This comment has been minimized.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 28, 2026
@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg: 🔥 warming; proof passed, review follow-up or readiness checks remain. Hatch with @clawsweeper hatch when eligible.

Rules and details

Hatchability:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

About:

  • Eggs appear after real-behavior proof passes. They are collectible flavor only.
  • Review momentum changes the shell state: follow-up work warms it, re-review makes it wobble, and a clean final review lets it hatch.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: XL and removed size: L labels May 28, 2026
@BingqingLyu

This comment was marked as spam.

@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 28, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 09da62fac6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +76 to +78
const snapshot = await getSessionGoal({
...resolveGoalSessionScope(options),
persist: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist goal accounting for get_goal reads

When a goal is created before the session has a fresh token snapshot, this read-only path calls getSessionGoal with persist: false, which also forces adoptFreshBaseline: false. In that scenario, later get_goal calls keep returning the stale tokenStartFresh: false state with tokensUsed unchanged, so token budgets never become effective for the model unless the user happens to run /goal manually; this contradicts the intended “adopt the next fresh snapshot” behavior for goals created early in a session.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f3835efaa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +186 to +189
const tokensUsed =
totalTokens === undefined || shouldAdoptFreshStart || shouldHoldStaleStart
? goal.tokensUsed
: Math.max(goal.tokensUsed, Math.max(0, totalTokens - tokenStart));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Freeze token usage after goal completion

When a goal has already been marked complete, later /goal or get_goal reads still pass through this accounting path and recompute tokensUsed from the current session total. In any session that continues after completing a goal without immediately clearing it, the completed goal's usage keeps growing with unrelated follow-up turns, so the final usage shown for the achieved objective is no longer the usage at completion even though complete is treated as terminal elsewhere.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added the mantis: telegram-visible-proof Mantis should capture Telegram visible proof. label May 28, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0df5647081

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +245 to +248
const resetsBudgetWindow =
options.status === "active" &&
(accounted.status === "budget_limited" || accounted.status === "usage_limited");
const freshTokenStart = resetsBudgetWindow ? resolveEntryFreshTotalTokens(entry) : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset over-budget inactive goals on resume

When a paused or blocked goal with a token budget accumulates enough fresh session tokens to meet the budget, accountGoalUsage updates tokensUsed but keeps the inactive status, so this check does not reset the budget window on /goal resume. The command returns an active goal whose tokensUsed >= tokenBudget, and the next status read or usage persist immediately flips it back to budget_limited, making resume effectively a no-op for paused/blocked goals that crossed the budget while inactive.

Useful? React with 👍 / 👎.

@steipete steipete force-pushed the core-thread-goals branch from 552c658 to 0a12400 Compare May 28, 2026 15:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a12400fff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tui/embedded-backend.ts Outdated
}

async runGoalCommand(opts: Parameters<NonNullable<TuiBackend["runGoalCommand"]>>[0]) {
const { canonicalKey, storePath, entry } = loadSessionEntry(opts.sessionKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route local global goals to the selected agent

In local TUI mode this loads /goal state with only the literal session key, so when the current session is global and the operator has selected a non-default agent, loadSessionEntry() falls back to the default agent store rather than the selected agent's global store. The gateway resolver already requires an explicit agentId for global/unknown keys, so /goal start/status/clear from openclaw tui --local can create or read the goal under main while the footer and session list are scoped to the selected agent.

Useful? React with 👍 / 👎.

@steipete steipete force-pushed the core-thread-goals branch 2 times, most recently from e8301e9 to 1293575 Compare May 28, 2026 16:17
@steipete steipete requested a review from a team as a code owner May 28, 2026 16:17
@steipete steipete self-assigned this May 29, 2026
@clawsweeper clawsweeper Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 29, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2397255fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +131 to +135
const goal = await updateSessionGoalStatus({
...resolveGoalSessionScope(options),
status: status as (typeof MODEL_UPDATABLE_SESSION_GOAL_STATUSES)[number],
...(note ? { note } : {}),
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve update_goal results through turn persistence

When update_goal runs during an agent turn that already loaded a goal, this writes the new status directly to the session store but never refreshes the agent command's in-memory session entry. Later turn persistence merges the stale working-copy entry back into the store, and because that entry still contains the old goal object, it can overwrite the completed/blocked status before the run finishes. This affects normal model-driven update_goal completion/blocking; update the live session entry/store after this write or avoid carrying stale goal fields into later persistence.

Useful? React with 👍 / 👎.

@openclaw-mantis

Copy link
Copy Markdown

Mantis Telegram Desktop Proof

Summary: Mantis captured native Telegram Desktop before/after GIFs showing the new /goal replies in chat.

Main screenshot This PR screenshot
Baseline native Telegram Desktop screenshot Candidate native Telegram Desktop screenshot
Main This PR
Baseline native Telegram Desktop proof GIF Candidate native Telegram Desktop proof GIF

Motion-trimmed clips:

Raw QA files: https://artifacts.openclaw.ai/mantis/telegram-desktop/pr-87469/run-26655798776-1/index.json

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28dc756c23

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const queuedRunReadiness = createQueuedRunReadiness();
this.runs.set(runId, {
sessionKey: opts.sessionKey,
agentId: opts.agentId,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate agentId on local global chat events

When openclaw tui --local is in global scope with a non-default selected agent, this newly stores the run's agentId, but the local backend's emitChatDelta/emitChatFinal/emitChatAborted/chat.side_result payloads still only send sessionKey: "global". src/tui/tui-event-handlers.ts now rejects global events without agentId unless the selected agent is the default, so /agent work followed by a global local send will drop the stream/final/abort events and leave the TUI without the response even though the run is scoped and executing.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Verification for head 3601c3d2bef1bee9039fda6dfa1c7f23eaded983:

Behavior addressed: /goal persists session goal state, propagates it through session rows/events, and renders current goal state in the Web UI and TUI while preserving selected-agent global session scoping.
Real environment tested: local macOS checkout plus Blacksmith Testbox via Crabbox.
Exact steps or command run after this patch:

  • node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo
  • node scripts/run-oxlint.mjs src/gateway/server-chat.agent-events.test.ts src/gateway/server-methods/sessions.abort-agent-scope.test.ts src/gateway/server.sessions.create.test.ts src/tui/embedded-backend.test.ts ui/src/ui/app-chat.test.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-gateway.sessions.node.test.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/controllers/sessions.test.ts src/commands/doctor.runs-legacy-state-migrations-yes-mode-without.e2e.test.ts && git diff --check
  • pnpm test src/gateway/server-methods/sessions.abort-agent-scope.test.ts src/gateway/server-methods/chat.abort-persistence.test.ts src/gateway/server.sessions.reset-hooks.test.ts src/gateway/server.sessions.create.test.ts src/gateway/server.sessions.compaction.test.ts src/gateway/server.sessions.list-changed.test.ts src/gateway/server-methods/sessions.send-followup-status.test.ts src/gateway/server-methods/agent.test.ts src/gateway/server-methods/chat.directive-tags.test.ts src/gateway/server-methods/chat.send-deleted-agent.test.ts ui/src/ui/chat/slash-command-executor.node.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/session-goal.test.ts src/tui/embedded-backend.test.ts -- --reporter=verbose --hookTimeout=120000
  • pnpm test src/gateway/server-chat.agent-events.test.ts src/gateway/server-methods/sessions.abort-agent-scope.test.ts src/gateway/server.sessions.create.test.ts src/tui/embedded-backend.test.ts ui/src/ui/app-chat.test.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-gateway.sessions.node.test.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/controllers/sessions.test.ts -- --reporter=verbose --hookTimeout=120000
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --thinking low --stream-engine-output
  • node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --blacksmith-org openclaw --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job check --blacksmith-ref core-thread-goals --idle-timeout 45m --ttl 90m --timing-json -- corepack pnpm test src/gateway/server-methods/sessions.abort-agent-scope.test.ts src/gateway/server-methods/chat.abort-persistence.test.ts src/gateway/server.sessions.reset-hooks.test.ts src/gateway/server.sessions.create.test.ts src/gateway/server.sessions.compaction.test.ts src/gateway/server.sessions.list-changed.test.ts src/gateway/server-methods/sessions.send-followup-status.test.ts src/gateway/server-methods/agent.test.ts src/gateway/server-methods/chat.directive-tags.test.ts src/gateway/server-methods/chat.send-deleted-agent.test.ts src/gateway/server-chat.agent-events.test.ts src/tui/embedded-backend.test.ts ui/src/ui/chat/slash-command-executor.node.test.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/session-goal.test.ts ui/src/ui/app-chat.test.ts ui/src/ui/app-gateway.node.test.ts ui/src/ui/app-gateway.sessions.node.test.ts
    Evidence after fix: autoreview reported no accepted/actionable findings; local focused tests passed; Blacksmith Testbox via Crabbox tbx_01kstmf0j5cspsk98vd7tq9yx6 passed 766 tests with exit 0; required GitHub dependency-guard is passing.
    Observed result after fix: session goal state is carried through server/session event paths and rendered by Web UI/TUI tests without selected-global agent leakage.
    What was not tested: manual browser screenshot pass and full pnpm check were not run; an earlier full pnpm check:changed Testbox pass hit the workflow step timeout edge after clearing the previously failing lint shard, so the final remote proof used the focused changed-surface suite above.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6006871d80

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1394 to +1395
const p = params;
const key = requireSessionKey(p.key, respond);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope sessions.describe to the requested agent

When a client is viewing the literal global session for a non-default agent, this handler still has no agentId path and the lookup below calls resolveGatewaySessionTargetFromKey(key, cfg) without an override, so sessions.describe describes the default agent's global row while the newly updated list/history/send paths use the selected agent. Add agentId to the describe params and pass it through the same global-agent resolution used by the other session methods.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Verification after the final fixup on current PR head 76a292fc2213c13ae95f02ef6e5e763e552de69b:

Behavior addressed: /goal persists session goal state, selected-global agent scope is preserved across gateway/UI/TUI paths, and the web UI now renders the current goal summary/status/usage.
Real environment tested: Blacksmith Testbox through Crabbox (provider=blacksmith-testbox, tbx_01kstpn5cjrcxydjgqf5098hkp, Actions run https://github.com/openclaw/openclaw/actions/runs/26660425515).
Exact steps or command run after this patch:
node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --blacksmith-org openclaw --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job check --blacksmith-ref core-thread-goals --idle-timeout 45m --ttl 90m --timing-json -- corepack pnpm test src/agents/agent-command.live-model-switch.test.ts src/gateway/server-methods/agent.test.ts src/gateway/server-methods/chat.directive-tags.test.ts src/config/sessions.cache.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/session-goal.test.ts

Evidence after fix: Testbox passed 4 Vitest shards / 373 tests with exitCode=0.
Observed result after fix: gateway agent/session/chat dispatch tests, runtime session-cache tests, agent command tests, and web goal/session subscription tests all passed on Linux Testbox.
What was not tested: full pnpm check:changed; local full core-test typecheck currently hits unrelated latest-main src/agents/bash-tools.exec-host-node.test.ts fixture type errors outside this PR.

Autoreview: .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --thinking low --stream-engine-output returned clean with no accepted/actionable findings.
Required checks: dependency-guard passed on https://github.com/openclaw/openclaw/actions/runs/26660416620/job/78581287823.

@steipete

Copy link
Copy Markdown
Contributor Author

Verification after final rebase/fixup on current PR head 463728c350da8a98c758ba4da03120676eb19603:

Behavior addressed: /goal persists session goal state, selected-global agent scope is preserved across gateway/UI/TUI/chat send/chat inject paths, and the web UI now renders the current goal summary/status/usage.
Real environment tested: Blacksmith Testbox through Crabbox (provider=blacksmith-testbox, tbx_01kstq3191m5dtrc0305tjdvny, Actions run https://github.com/openclaw/openclaw/actions/runs/26660765335).
Exact steps or command run after this patch:
node scripts/crabbox-wrapper.mjs run --provider blacksmith-testbox --blacksmith-org openclaw --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job check --blacksmith-ref core-thread-goals --idle-timeout 45m --ttl 90m --timing-json -- corepack pnpm test src/agents/agent-command.live-model-switch.test.ts src/gateway/server-methods/agent.test.ts src/gateway/server-methods/chat.directive-tags.test.ts src/config/sessions.cache.test.ts ui/src/ui/controllers/sessions.test.ts ui/src/ui/session-goal.test.ts

Evidence after fix: Testbox passed 4 Vitest shards / 374 tests with exitCode=0.
Observed result after fix: gateway agent/session/chat dispatch/chat inject tests, runtime session-cache tests, agent command tests, and web goal/session subscription tests all passed on Linux Testbox.
What was not tested: full pnpm check:changed; local full core-test typecheck currently hits unrelated latest-main src/agents/bash-tools.exec-host-node.test.ts fixture type errors outside this PR.

Autoreview: .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --thinking low --stream-engine-output returned clean with no accepted/actionable findings.
Required checks: dependency-guard passed on https://github.com/openclaw/openclaw/actions/runs/26660758136/job/78582437572.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui channel: telegram Channel integration: telegram docs Improvements or additions to documentation extensions: codex gateway Gateway runtime maintainer Maintainer-authored PR mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 🎥 video Contributor real behavior proof includes video or recording evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants