Skip to content

feat: pursue a goal autonomously #270

Merged
chengluyu merged 65 commits into
MoonshotAI:mainfrom
chengluyu:feat/goal-impl/1
Jun 2, 2026
Merged

feat: pursue a goal autonomously #270
chengluyu merged 65 commits into
MoonshotAI:mainfrom
chengluyu:feat/goal-impl/1

Conversation

@chengluyu
Copy link
Copy Markdown
Collaborator

This PR implements the “goal” feature, which has been highly requested for many times.

Related Issue

TBA.

Problem

TBA.

What changed

TBA.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

chengluyu added 30 commits May 30, 2026 02:54
Copy link
Copy Markdown

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

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: e68378e8ba

ℹ️ 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 packages/agent-core/src/agent/turn/index.ts Outdated
Comment thread packages/agent-core/src/agent/turn/index.ts
Comment thread apps/kimi-code/src/tui/commands/registry.ts Outdated
Comment thread apps/kimi-code/src/tui/commands/goal.ts
Comment thread apps/kimi-code/src/tui/commands/goal.ts Outdated
Copy link
Copy Markdown

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

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: b0815f5ea1

ℹ️ 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 packages/agent-core/src/agent/turn/index.ts
Comment thread packages/agent-core/src/agent/turn/index.ts Outdated
Comment thread packages/agent-core/src/agent/injection/goal.ts Outdated
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 2, 2026

pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@a22a66c
npx https://pkg.pr.new/@moonshot-ai/kimi-code@a22a66c

commit: a22a66c

Copy link
Copy Markdown

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

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: b7f34e153d

ℹ️ 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 apps/kimi-code/src/cli/run-prompt.ts
Comment thread packages/agent-core/src/loop/turn-step.ts Outdated
Comment thread apps/kimi-code/src/tui/kimi-tui.ts Outdated
Comment thread packages/agent-core/src/tools/builtin/goal/update-goal.ts
Comment thread packages/agent-core/src/session/goal.ts
Copy link
Copy Markdown

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

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: 734b1d438d

ℹ️ 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 +605 to +607
if (!stopHookContinuationUsed) {
const stopBlock = await this.agent.hooks?.triggerBlock('Stop', {
signal,
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 Block Stop-hook continuations after budget exhaustion

When an active goal hits its token budget, afterStep returns stopTurn, but runTurn still invokes this shouldContinueAfterStop hook before the goal driver can mark the goal blocked. In sessions with a Stop hook that returns a block/continuation, this branch appends the hook prompt and returns continue: true, causing another model step after the hard budget has already been reached. Check stopForGoalBudget before allowing steer/Stop-hook continuations so configured token ceilings remain deterministic.

Useful? React with 👍 / 👎.

Comment on lines +64 to +66
const reservedGoal = this.session.metadata.custom?.['goal'];
const patchCustom = (payload.metadata as Partial<SessionMeta> | undefined)?.custom;
if (patchCustom !== undefined && 'goal' in patchCustom) {
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 Reserve goal metadata on create and fork

This guard only protects updateSessionMetadata, but the public create/fork session metadata path is copied directly into Session.metadata.custom, where goal is now reserved. An SDK caller that creates or forks a session with custom metadata { goal: ... } can still seed arbitrary goal state outside the lifecycle methods and flag gate, and later getGoal()/goal driving will treat that host metadata as the current goal. Apply the same reservation to create/fork metadata inputs.

Useful? React with 👍 / 👎.

Comment on lines +725 to +728
typeof state.status === 'string' &&
ALL_GOAL_STATUSES.has(state.status) &&
typeof state.turnsUsed === 'number' &&
typeof state.tokensUsed === 'number' &&
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 Reject goal records missing wall-clock fields

normalizeMetadata() relies on this predicate before treating metadata.custom.goal as a SessionGoalState, but this accepts records that lack required fields such as wallClockMs, createdAt, and actor timestamps. For an imported/forked session with the checked subset present, the malformed record is kept and later snapshots compute elapsed time from undefined, producing NaN/invalid goal status output instead of dropping the corrupt goal. Require the full numeric/string fields used by toSnapshot() and budget math here.

Useful? React with 👍 / 👎.

Comment on lines +62 to +63
await store.setBudgetLimits({ budgetLimits: budget, actor: 'model' });
return { output: `Goal budget set: ${formatBudget(args.value, args.unit)}.` };
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 Stop immediately when SetGoalBudget is already exhausted

When the model records a user-stated budget after the goal has already spent at least that much (for example it has used one turn and calls SetGoalBudget({ value: 1, unit: 'turns' }) as instructed), this persists an over-budget goal but returns an ordinary tool result. Because the goal driver only checks budgets at the turn boundary, the current tool batch and even the next model step can continue before the goal is blocked; return a stop hint or block immediately when the new snapshot is over budget.

Useful? React with 👍 / 👎.

@chengluyu chengluyu changed the title Support pursuing a goal autonomously feat: pursue a goal autonomously Jun 2, 2026
@chengluyu chengluyu merged commit ac37d74 into MoonshotAI:main Jun 2, 2026
8 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 2, 2026
Copy link
Copy Markdown

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

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: c0aacc0f6e

ℹ️ 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 +157 to +158
if (choice === 'auto' || choice === 'yolo') {
if (!(await setPermissionForGoal(host, choice))) return;
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 Avoid switching permission before goal creation succeeds

In manual mode, if a goal already exists and the user enters /goal <new objective> without replace, choosing Auto/YOLO here changes the session permission before startGoal() later calls createGoal() and rejects with GOAL_ALREADY_EXISTS. The result is that no goal starts, but the session is left in a more permissive mode than before; preflight the goal creation conflict first or restore the previous permission when creation fails.

Useful? React with 👍 / 👎.

Comment on lines +317 to +320
// The wall-clock anchor is a runtime timestamp; a persisted one is stale
// (it predates the downtime). Drop it so resumed time isn't counted as
// pursuit — `resumeGoal` re-anchors a fresh interval.
state.wallClockResumedAt = 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 Preserve active wall-clock time when resuming goals

When a session is resumed with an active goal, clearing wallClockResumedAt here before demoting it to paused means applyStatus() cannot fold the elapsed active interval into wallClockMs. If the process exits or crashes while an active goal with a wall-clock budget has been running, that time is discarded on the next resume, so /goal resume can continue with more time remaining than the configured hard budget should allow.

Useful? React with 👍 / 👎.

Comment on lines +399 to +400
if (input.completionCriterion !== undefined && input.completionCriterion.trim().length > 0) {
state.completionCriterion = input.completionCriterion.trim();
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 Cap completion criteria before persisting goals

When the SDK or CreateGoal tool supplies a very large completionCriterion, this path trims it but bypasses the 4000-character cap applied to the objective, and the goal injector later repeats that criterion in every active/paused/blocked goal reminder. A long criterion can therefore bloat state.json and every continuation prompt despite the objective length guard; apply a comparable limit before storing it.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant