Skip to content

feat(skills): suggest saving detected reusable workflows by default#100692

Merged
steipete merged 1 commit into
mainfrom
feat/workshop-suggest-tier-65fd03
Jul 6, 2026
Merged

feat(skills): suggest saving detected reusable workflows by default#100692
steipete merged 1 commit into
mainfrom
feat/workshop-suggest-tier-65fd03

Conversation

@steipete

@steipete steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Skill capture had two modes with nothing in between: off (the default — durable-instruction signals detected at agent-end were silently dropped) and skills.workshop.autonomous.enabled (proposals filed directly). Users repeatedly ask for the agent to get better at repeated tasks, but full autonomous capture stays opt-in for good reasons. The detection machinery already existed and did nothing for the default configuration.

Closes #95477 (scoped: suggestion tier; full post-task self-reflection remains future work).

Why This Change Was Made

Default-on suggest tier between off and autonomous, reusing existing seams end to end:

  • runSkillResearchAutoCapture (src/skills/research/autocapture.ts): when autonomy is off, the same signal extraction now records a one-shot pendingSkillSuggestion on the session entry instead of returning early. Same eligibility gates (success only; no cron/heartbeat/subagent/active-memory sessions), same pending-proposal dedupe, plus a live-skill guard (existing skills don't get "save this as a skill" suggestions).
  • Replay-proof by construction: a lastSkillSuggestionSignalHash fingerprint (sha256 of the signal evidence) is stored alongside, so the same correction re-extracted from transcript history on later turns never re-suggests — the invariant the coordinated capture design (improve: skill auto-capture catches reactive corrections and routes them to existing skills #100576 review) requires, landed here first.
  • One-shot consumption (src/config/sessions/skill-suggestions.ts): atomic record/consume via patchSessionEntry — an unconsumed suggestion is never replaced, the next non-heartbeat interactive turn atomically clears the flag and injects exactly one user-role context line (inbound-meta.ts, same seam and conventions as the active-goal line from feat(goals): keep active session goals in per-turn context + continuance QA scenarios #100468, quote-sanitized and length-bounded):
    A reusable workflow ("<skillName>") was detected last turn — offer to save it as a skill via skill_workshop if the user agrees.
    Competing/queued turns see cleared state; heartbeats neither inject nor consume.
  • The agent offers; the user decides. The line instructs the agent to offer — the proposal (if the user agrees) goes through the normal skill_workshop pending/approval flow. autonomous.enabled behavior is unchanged (direct proposals, no suggestion line).
  • No new config keys. Session store is the only state owner (pendingSkillSuggestion + fingerprint registered as reserved session-entry slot keys). System prompt and prior transcript bytes untouched.

User Impact

Out of the box, OpenClaw now notices "from now on…"-style durable instructions and offers — once, on the next turn — to save them as a reviewable skill. Saying yes produces a normal pending Skill Workshop proposal; ignoring it costs nothing further. Operators who enabled autonomous capture see no change. Docs: "Suggested skills" section in skill-workshop.

Evidence

  • Focused Testbox suites green on the final tree: src/skills/research/autocapture.test.ts (suggest recorded on default config; not recorded when autonomous/signal absent/pending proposal/live skill/blocked trigger; fingerprint replay guard), src/auto-reply/reply/inbound-meta.test.ts (line format, sanitization, absence), src/auto-reply/reply/get-reply-run.media-only.test.ts (one-shot consume, heartbeat exclusion, queued-turn behavior).
  • Structured second-model review (Codex, gpt-5.5) of the diff: clean.
  • git diff --check, formatting, docs formatting clean.
  • Release-note context: user-facing feat — the Skill Workshop now suggests saving detected reusable workflows by default; the agent offers, the user decides, approval flow unchanged.

…95477)

Adds the middle tier between capture-off and autonomous capture: when
autonomy is disabled, detected durable-instruction signals record a
one-shot pendingSkillSuggestion on the session entry (signal-hash
fingerprint prevents transcript-history replay), and the next
non-heartbeat turn atomically consumes it and injects one bounded
user-role line offering to save the skill. The agent offers, the user
decides; skill_workshop approval flow unchanged; no new config.
@steipete
steipete merged commit 1e2e7fb into main Jul 6, 2026
1 check passed
@steipete
steipete deleted the feat/workshop-suggest-tier-65fd03 branch July 6, 2026 06:54
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: L maintainer Maintainer-authored PR labels Jul 6, 2026

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

Copy link
Copy Markdown
Contributor

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: 842163cfe5

ℹ️ 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 +817 to +821
const consumed = await consumeSessionSkillSuggestion({
agentId,
sessionKey,
storePath,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Defer consuming suggestions until a run is admitted

When a session has pendingSkillSuggestion, this clears it before active-run admission has succeeded. If a new non-heartbeat message arrives while the previous run is still active, resolvePreparedReplyQueueState can return the “Previous run is still shutting down” reply after waiting (src/auto-reply/reply/get-reply-run-queue.ts:43-52), so runReplyAgent is never called and the projected context is never shown; the persisted suggestion has already been removed, so the next real turn will not offer to save the workflow. Consume only after admission is guaranteed to continue, or restore the flag on early reply paths.

Useful? React with 👍 / 👎.

vincentkoc added a commit to zhangqueping/openclaw that referenced this pull request Jul 6, 2026
* origin/main: (1287 commits)
  fix(android): block loopback canvas navigation (openclaw#99874)
  fix(hooks): suppress unhandled stdout/stderr stream errors in gmail watcher (openclaw#100519)
  fix(memory-core): guard qmd mcporter JSON.parse against non-JSON stdout (openclaw#98381)
  fix(build): fall back to tsx for build TypeScript scripts (openclaw#91262)
  feat(skills): suggest saving detected reusable workflows by default (openclaw#95477) (openclaw#100692)
  docs(changelog): remove generated release-note entries
  feat(telegram): offer BotFather web app flow in setup help and docs (openclaw#100540)
  fix(ios): unify Talk and Settings row typography on one branded detail row (openclaw#100515)
  feat(gateway): add persisted crash-loop breaker and fatal-config exit contract
  refactor(macos): lock and unify PortGuardian tunnel record persistence so concurrent app instances cannot lose orphan records (openclaw#100601)
  fix: stop reconnecting on protocol mismatch (openclaw#98414)
  fix(maint): reuse recent hosted gates after rebase (openclaw#100663)
  fix(ui): reopen web terminals without stale content (openclaw#100665)
  fix(browser): diagnose empty WSL2 Chrome replies (openclaw#100590)
  fix(ios): chat snaps back to bottom when scrolling to top via status-bar tap (openclaw#100502)
  Treat already-compacted CLI compaction as no-op (openclaw#99136)
  docs(changelog): remove direct main fix entry
  fix(feishu): strip internal tool-trace banners from outbound text (openclaw#98705)
  fix(message): thread --limit through to CLI formatter and surface provider pagination hints (openclaw#99089)
  fix(voyage): close response body stream when batch output JSONL parsing throws (openclaw#98840)
  ...

# Conflicts:
#	extensions/memory-wiki/package.json
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
…penclaw#95477) (openclaw#100692)

Adds the middle tier between capture-off and autonomous capture: when
autonomy is disabled, detected durable-instruction signals record a
one-shot pendingSkillSuggestion on the session entry (signal-hash
fingerprint prevents transcript-history replay), and the next
non-heartbeat turn atomically consumes it and injects one bounded
user-role line offering to save the skill. The agent offers, the user
decides; skill_workshop approval flow unchanged; no new config.
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…penclaw#95477) (openclaw#100692)

Adds the middle tier between capture-off and autonomous capture: when
autonomy is disabled, detected durable-instruction signals record a
one-shot pendingSkillSuggestion on the session entry (signal-hash
fingerprint prevents transcript-history replay), and the next
non-heartbeat turn atomically consumes it and injects one bounded
user-role line offering to save the skill. The agent offers, the user
decides; skill_workshop approval flow unchanged; no new config.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Post-task self-reflection for skill auto-creation (inspired by Hermes + SkillClaw), + prefix cache optimization (inspired by Reasonix)

1 participant