Skip to content

Commit a509c48

Browse files
authored
feat: add core session goals (#87469)
* feat: add core session goals * feat: polish session goals in tui * fix: resolve goal tool session stores * fix: keep get goal read-only * fix: migrate legacy goal session slots * fix: persist goal token accounting * fix: validate goal session rows * refactor: remove unshipped goal legacy handling * fix: handle goal commands in local tui * fix: satisfy goal tool display checks * fix: reset goal budget on overdue resume * feat: surface session goals across control surfaces * test: update gateway protocol test import * test: align goal fixture types with protocol * fix: scope selected global transcript usage fallback * fix: scope selected global web subscriptions * fix: preserve selected global agent during chat dispatch * fix: scope chat inject to selected global agents
1 parent 057be10 commit a509c48

138 files changed

Lines changed: 10462 additions & 483 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,26 @@
361361
}
362362
}
363363
},
364+
"get_goal": {
365+
"emoji": "🎯",
366+
"title": "Get Goal",
367+
"detailKeys": []
368+
},
369+
"create_goal": {
370+
"emoji": "🎯",
371+
"title": "Create Goal",
372+
"detailKeys": [
373+
"objective",
374+
"token_budget"
375+
]
376+
},
377+
"update_goal": {
378+
"emoji": "🎯",
379+
"title": "Update Goal",
380+
"detailKeys": [
381+
"status"
382+
]
383+
},
364384
"update_plan": {
365385
"emoji": "🗺️",
366386
"title": "Update Plan",

docs/cli/tui.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Notes:
4343
- Local mode uses the embedded agent runtime directly. Most local tools work, but Gateway-only features are unavailable.
4444
- Local mode adds `/auth [provider]` inside the TUI command surface.
4545
- Plugin approval gates still apply in local mode. Tools that require approval prompt for a decision in the terminal; nothing is silently auto-approved because the Gateway is not involved.
46+
- Session [goals](/tools/goal) appear in the footer and can be managed with `/goal`.
4647

4748
## Examples
4849

@@ -87,3 +88,4 @@ rerun `openclaw config validate`. See [TUI](/web/tui) and [Config](/cli/config).
8788

8889
- [CLI reference](/cli)
8990
- [TUI](/web/tui)
91+
- [Goal](/tools/goal)

docs/docs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,7 @@
13331333
"group": "Agent coordination",
13341334
"pages": [
13351335
"tools/agent-send",
1336+
"tools/goal",
13361337
"tools/steer",
13371338
"tools/subagents",
13381339
"tools/acp-agents",

docs/tools/goal.md

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
---
2+
doc-schema-version: 1
3+
summary: "Session goals: durable per-session objectives, /goal controls, model goal tools, token budgets, and TUI status"
4+
read_when:
5+
- You want OpenClaw to keep one objective visible across a long session
6+
- You need to pause, resume, block, complete, or clear a session goal
7+
- You want to understand the get_goal, create_goal, and update_goal tools
8+
- You want to see how goals appear in the TUI
9+
title: "Goal"
10+
---
11+
12+
# Goal
13+
14+
A **goal** is one durable objective attached to the current OpenClaw session.
15+
It gives the agent and the operator a shared target for long-running work,
16+
without turning that target into a background task, reminder, cron job, or
17+
standing order.
18+
19+
Goals are session state. They move with the session key, survive process
20+
restarts, show up in `/goal`, are available to the model through the goal
21+
tools, and appear in the TUI footer when the active session has one.
22+
23+
## Quick start
24+
25+
Set a goal:
26+
27+
```text
28+
/goal start get CI green for PR 87469 and push the fix
29+
```
30+
31+
Check it:
32+
33+
```text
34+
/goal
35+
```
36+
37+
Pause it when work is intentionally waiting:
38+
39+
```text
40+
/goal pause waiting for CI
41+
```
42+
43+
Resume it:
44+
45+
```text
46+
/goal resume
47+
```
48+
49+
Mark it complete:
50+
51+
```text
52+
/goal complete pushed and verified
53+
```
54+
55+
Clear it:
56+
57+
```text
58+
/goal clear
59+
```
60+
61+
## What goals are for
62+
63+
Use a goal when a session has a concrete outcome that should remain visible
64+
across many turns:
65+
66+
- A PR closeout: fix, verify, autoreview, push, and open or update the PR.
67+
- A debug run: reproduce the bug, identify the owning surface, patch, and prove
68+
the fix.
69+
- A docs pass: read the relevant docs, write the new page, cross-link it, and
70+
verify the docs build.
71+
- A maintenance task: inspect current state, make bounded changes, run the right
72+
checks, and report what changed.
73+
74+
A goal is not a task queue. Use [Task Flow](/automation/taskflow),
75+
[tasks](/automation/tasks), [cron jobs](/automation/cron-jobs), or
76+
[standing orders](/automation/standing-orders) when work should run detached,
77+
repeat on a schedule, fan out into managed sub-work, or persist as a policy.
78+
79+
## Command reference
80+
81+
`/goal` without arguments prints the current goal summary:
82+
83+
```text
84+
Goal
85+
Status: active
86+
Objective: get CI green for PR 87469 and push the fix
87+
Tokens used: 12k
88+
Token budget: 12k/50k
89+
90+
Commands: /goal pause, /goal complete, /goal clear
91+
```
92+
93+
Commands:
94+
95+
- `/goal` or `/goal status` shows the current goal.
96+
- `/goal start <objective>` creates a new goal for the current session.
97+
- `/goal set <objective>` and `/goal create <objective>` are aliases for
98+
`start`.
99+
- `/goal pause [note]` pauses an active goal.
100+
- `/goal resume [note]` resumes a paused, blocked, usage-limited, or
101+
budget-limited goal.
102+
- `/goal complete [note]` marks the goal achieved.
103+
- `/goal done [note]` is an alias for `complete`.
104+
- `/goal block [note]` marks the goal blocked.
105+
- `/goal blocked [note]` is an alias for `block`.
106+
- `/goal clear` removes the goal from the session.
107+
108+
Only one goal can exist on a session at a time. Starting a second goal fails
109+
until the current one is cleared.
110+
111+
## Statuses
112+
113+
Goals use a small status set:
114+
115+
- `active`: the session is pursuing the goal.
116+
- `paused`: the operator paused the goal; `/goal resume` makes it active again.
117+
- `blocked`: the agent or operator reported a real blocker; `/goal resume`
118+
makes it active again when new information or state is available.
119+
- `budget_limited`: the configured token budget was reached; `/goal resume`
120+
restarts pursuit from the same objective.
121+
- `usage_limited`: reserved for usage-limit stop states; `/goal resume`
122+
restarts pursuit when allowed.
123+
- `complete`: the goal was achieved. Complete goals are terminal; use
124+
`/goal clear` before starting another goal.
125+
126+
`/new` and `/reset` clear the current session goal because they intentionally
127+
start fresh session context.
128+
129+
## Token budgets
130+
131+
Goals can have an optional positive token budget. The budget is stored with the
132+
goal and measured from the session's fresh token count at creation time. If the
133+
current session only has stale or unknown token usage when the goal starts,
134+
OpenClaw waits for the next fresh session token snapshot and uses that as the
135+
baseline, so tokens spent before the goal existed are not charged to the goal.
136+
137+
When token usage reaches the budget, the goal changes to `budget_limited`. This
138+
does not delete the goal or erase the objective. It tells the operator and the
139+
agent that the goal is no longer actively being pursued until it is resumed or
140+
cleared.
141+
142+
Token budgets are a session-goal guardrail, not a billing cap. Provider quota,
143+
cost reporting, and context-window behavior still use the normal OpenClaw
144+
usage and model controls.
145+
146+
## Model tools
147+
148+
OpenClaw exposes three core goal tools to agent harnesses:
149+
150+
- `get_goal`: read the current session goal, including status, objective, token
151+
usage, and token budget.
152+
- `create_goal`: create a goal only when the user, system, or developer
153+
instructions explicitly request one. It fails if the session already has a
154+
goal.
155+
- `update_goal`: mark the goal `complete` or `blocked`.
156+
157+
The model cannot silently pause, resume, clear, or replace a goal. Those are
158+
operator/session controls through `/goal` and reset commands. This keeps the
159+
agent from quietly moving the target while preserving a clean path for the
160+
agent to report achievement or a genuine blocker.
161+
162+
The `update_goal` tool should mark a goal `complete` only when the objective is
163+
actually achieved. It should mark a goal `blocked` only when the same blocking
164+
condition has repeated and the agent cannot make meaningful progress without
165+
new user input or an external-state change.
166+
167+
## TUI
168+
169+
The TUI keeps the active session's goal visible in the footer next to the
170+
agent, session, model, run controls, and token counts.
171+
172+
Footer examples:
173+
174+
- `Pursuing goal (12k/50k)` for an active goal with a token budget.
175+
- `Goal paused (/goal resume)` for a paused goal.
176+
- `Goal blocked (/goal resume)` for a blocked goal.
177+
- `Goal hit usage limits (/goal resume)` for a usage-limited goal.
178+
- `Goal unmet (50k/50k)` for a budget-limited goal.
179+
- `Goal achieved (42k)` for a completed goal.
180+
181+
The footer is intentionally compact. Use `/goal` for the full objective, note,
182+
token budget, and available commands.
183+
184+
## Channel behavior
185+
186+
The `/goal` command works in command-capable OpenClaw sessions, including the
187+
TUI and chat surfaces that permit text commands. Goal state is attached to the
188+
session key, not the transport. If two surfaces use the same session, they see
189+
the same goal.
190+
191+
Goal state is not a delivery directive. It does not force replies through a
192+
channel, change queue behavior, approve tools, or schedule work.
193+
194+
## Troubleshooting
195+
196+
`Goal error: goal already exists` means the session already has a goal. Use
197+
`/goal` to inspect it, `/goal complete` if it is done, or `/goal clear` before
198+
starting a different objective.
199+
200+
`Goal error: goal not found` means the session has no goal yet. Start one with
201+
`/goal start <objective>`.
202+
203+
`Goal error: goal is already complete` means the goal is terminal. Clear it
204+
before starting or resuming another objective.
205+
206+
If token usage looks like `0` or stale, the active session may not have a fresh
207+
token snapshot yet. Usage refreshes as OpenClaw records session usage and
208+
transcript-derived totals.
209+
210+
## Related
211+
212+
- [Slash commands](/tools/slash-commands)
213+
- [TUI](/web/tui)
214+
- [Session tool](/concepts/session-tool)
215+
- [Compaction](/concepts/compaction)
216+
- [Task Flow](/automation/taskflow)
217+
- [Standing orders](/automation/standing-orders)

docs/tools/index.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,18 @@ The table lists representative tools so you can recognize the surface. It is
7878
not the full policy reference. For exact groups, defaults, and allow/deny
7979
semantics, use [Tools and custom providers](/gateway/config-tools).
8080

81-
| Category | Use when the agent needs to... | Representative tools | Read next |
82-
| ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
83-
| Runtime | Run commands, manage processes, or use provider-backed Python analysis | `exec`, `process`, `code_execution` | [Exec](/tools/exec), [Code execution](/tools/code-execution) |
84-
| Files | Read and change workspace files | `read`, `write`, `edit`, `apply_patch` | [Apply patch](/tools/apply-patch) |
85-
| Web | Search the web, search X posts, or fetch readable page content | `web_search`, `x_search`, `web_fetch` | [Web tools](/tools/web), [Web fetch](/tools/web-fetch) |
86-
| Browser | Operate a browser session | `browser` | [Browser](/tools/browser) |
87-
| Messaging and channels | Send replies or channel actions | `message` | [Agent send](/tools/agent-send) |
88-
| Sessions and agents | Inspect sessions, delegate work, steer another run, or report status | `sessions_*`, `subagents`, `agents_list`, `session_status` | [Sub-agents](/tools/subagents), [Session tool](/concepts/session-tool) |
89-
| Automation | Schedule work or respond to background events | `cron`, `heartbeat_respond` | [Automation](/automation) |
90-
| Gateway and nodes | Inspect Gateway state or paired target devices | `gateway`, `nodes` | [Gateway configuration](/gateway/configuration), [Nodes](/nodes) |
91-
| Media | Analyze, generate, or speak media | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` | [Media overview](/tools/media-overview) |
92-
| Large OpenClaw catalogs | Search and call many eligible tools without sending every schema to the model | `tool_search_code`, `tool_search`, `tool_describe` | [Tool Search](/tools/tool-search) |
81+
| Category | Use when the agent needs to... | Representative tools | Read next |
82+
| ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
83+
| Runtime | Run commands, manage processes, or use provider-backed Python analysis | `exec`, `process`, `code_execution` | [Exec](/tools/exec), [Code execution](/tools/code-execution) |
84+
| Files | Read and change workspace files | `read`, `write`, `edit`, `apply_patch` | [Apply patch](/tools/apply-patch) |
85+
| Web | Search the web, search X posts, or fetch readable page content | `web_search`, `x_search`, `web_fetch` | [Web tools](/tools/web), [Web fetch](/tools/web-fetch) |
86+
| Browser | Operate a browser session | `browser` | [Browser](/tools/browser) |
87+
| Messaging and channels | Send replies or channel actions | `message` | [Agent send](/tools/agent-send) |
88+
| Sessions and agents | Inspect sessions, delegate work, steer another run, or report status | `sessions_*`, `subagents`, `agents_list`, `session_status`, `goal` | [Goal](/tools/goal), [Sub-agents](/tools/subagents), [Session tool](/concepts/session-tool) |
89+
| Automation | Schedule work or respond to background events | `cron`, `heartbeat_respond` | [Automation](/automation) |
90+
| Gateway and nodes | Inspect Gateway state or paired target devices | `gateway`, `nodes` | [Gateway configuration](/gateway/configuration), [Nodes](/nodes) |
91+
| Media | Analyze, generate, or speak media | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` | [Media overview](/tools/media-overview) |
92+
| Large OpenClaw catalogs | Search and call many eligible tools without sending every schema to the model | `tool_search_code`, `tool_search`, `tool_describe` | [Tool Search](/tools/tool-search) |
9393

9494
<Note>
9595
Tool Search is an experimental OpenClaw agent surface. Codex harness runs use

docs/tools/slash-commands.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ Current source-of-truth:
153153
- `/commands` shows the generated command catalog.
154154
- `/tools [compact|verbose]` shows what the current agent can use right now.
155155
- `/status` shows execution/runtime status, Gateway and system uptime, plus provider usage/quota when available.
156+
- `/goal [status] | /goal start <objective> | /goal pause|resume|complete|block|clear` manages the current session's durable [goal](/tools/goal).
156157
- `/diagnostics [note]` is the owner-only support-report flow for Gateway bugs and Codex harness runs. It asks for explicit exec approval every time before running `openclaw gateway diagnostics export --json`; do not approve diagnostics with an allow-all rule. After approval, it sends a pasteable report with the local bundle path, manifest summary, privacy notes, and relevant session ids. In group chats, the approval prompt and report go to the owner privately. When the active session uses the OpenAI Codex harness, the same approval also sends relevant Codex feedback to OpenAI servers and the completed reply lists the OpenClaw session ids, Codex thread ids, and `codex resume <thread-id>` commands. See [Diagnostics Export](/gateway/diagnostics).
157158
- `/crestodian <request>` runs the Crestodian setup and repair helper from an owner DM.
158159
- `/tasks` lists active/recent background tasks for the current session.

docs/web/tui.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Notes:
5454
- Header: connection URL, current agent, current session.
5555
- Chat log: user messages, assistant replies, system notices, tool cards.
5656
- Status line: connection/run state (connecting, running, streaming, idle, error).
57-
- Footer: connection state + agent + session + model + think/fast/verbose/trace/reasoning + token counts + deliver.
57+
- Footer: connection state + agent + session + model + goal state + think/fast/verbose/trace/reasoning + token counts + deliver.
5858
- Input: text editor with autocomplete.
5959

6060
## Mental model: agents + sessions
@@ -68,6 +68,9 @@ Notes:
6868
- `per-sender` (default): each agent has many sessions.
6969
- `global`: the TUI always uses the `global` session (the picker may be empty).
7070
- The current agent + session are always visible in the footer.
71+
- If the session has a [goal](/tools/goal), the footer shows its compact state
72+
such as `Pursuing goal`, `Goal paused (/goal resume)`, or
73+
`Goal achieved`.
7174
- When started without `--session`, gateway-mode TUI resumes the last selected session for the same gateway, agent, and session scope if that session still exists. Passing `--session`, `/session`, `/new`, or `/reset` remains explicit.
7275

7376
## Sending + delivery
@@ -116,6 +119,7 @@ Session controls:
116119
- `/trace <on|off>`
117120
- `/reasoning <on|off|stream>`
118121
- `/usage <off|tokens|full>`
122+
- `/goal [status] | /goal start <objective> | /goal pause|resume|complete|block|clear`
119123
- `/elevated <on|off|ask|full>` (alias: `/elev`)
120124
- `/activation <mention|always>`
121125
- `/deliver <on|off>`

extensions/codex/src/app-server/transcript-mirror.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ export async function mirrorCodexAppServerTranscript(params: {
358358
emitSessionTranscriptUpdate({
359359
sessionFile: params.sessionFile,
360360
...(params.sessionKey ? { sessionKey: params.sessionKey } : {}),
361+
...(params.agentId ? { agentId: params.agentId } : {}),
361362
message: update.message,
362363
messageId: update.messageId,
363364
messageSeq: update.messageSeq,

extensions/telegram/src/bot-message-dispatch.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ async function mirrorTelegramAssistantReplyToTranscript(params: {
383383
emitSessionTranscriptUpdate({
384384
sessionFile,
385385
sessionKey: params.sessionKey,
386+
agentId: params.route.agentId,
386387
message: appendedMessage,
387388
messageId,
388389
});

0 commit comments

Comments
 (0)