Skip to content

fix(coding-agent): rediscover skills when a task agent autoloads one the session has not seen - #15723

Open
shyamsivakumar wants to merge 4 commits into
can1357:mainfrom
shyamsivakumar:fix/autoload-skills-refresh
Open

shyamsivakumar wants to merge 4 commits into
can1357:mainfrom
shyamsivakumar:fix/autoload-skills-refresh

Conversation

@shyamsivakumar

Copy link
Copy Markdown

What

I hit this when an agent's new skill was silently skipped in a long-running session; this reuses the existing refreshSkills to fix it.

Before a task spawn resolves an agent's autoload-skills, the spawn now checks that every named skill is in the parent session's skill list. If one is missing, it calls the session's existing refreshSkills() once, then resolves as before. When every named skill is already known, nothing changes.

Why

Agents are rediscovered on every task spawn, but the session's skill list is fixed at startup. resolveAutoloadSkills in task/structured-subagent.ts filters the agent's autoload-skills against that startup list, so a skill added after the session started was dropped with no warning: the agent ran without its skill.

Testing

Reproduction: a headless omp -p session in a fresh git repository creates .omp/skills/zebra-check/SKILL.md (body contains ZEBRA-4417) and .omp/agents/zebra-agent.md with autoload-skills: zebra-check, then spawns zebra-agent and asks for the password without reading files.

  • 18.10.4 unpatched: the child transcript contains no skill text, and the child answers NONE.
  • 18.10.4 with the same change applied to the installed bundle: the skill text appears in the child transcript, and the child answers ZEBRA-4417.

Checks on this branch:

  • bun run check:ts exits 0 (oxlint, oxfmt, and type checks for all packages).
  • bun test test/task test/discovery/agent-fields.test.ts test/skill-prompt-message.test.ts test/agent-session-tree-skill-injection.test.ts in packages/coding-agent: 561 pass, 0 fail.
  • check:rs and the full test suite were not run.

  • bun check passes (TypeScript half only: bun run check:ts)
  • Tested locally
  • CHANGELOG updated with the required attribution

…the session has not seen

Agents are rediscovered on every task spawn, but the parent session's skill
list is fixed at startup. An agent whose autoload-skills names a skill added
after startup got that skill silently dropped. Call the session's existing
refreshSkills() once before resolving autoload skills when a name is missing.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T15:33:21.460572Z 62cabfd New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@roboomp roboomp added agent Agent runtime planning and orchestration fix review:p1 triaged labels Oct 14, 2026
@roboomp

roboomp commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

P1 — focused fix for late-added task-agent skills; no overlapping fix found.
Should-fix: add a regression through task spawn, and credit the contributor in the changelog entry at packages/coding-agent/CHANGELOG.md:17.
Local bun test could not execute either task suite: this checkout lacks src/export/html/tool-views.generated.js; the PR reports a manual headless reproduction.
Thanks, @shyamsivakumar.

Not anchored to diff

  • packages/coding-agent/src/task/structured-subagent.ts:718 — should-fix — regression coverage: runStructuredSubagent() now refreshes only when an autoload name is absent, but the existing test/task/autoload-skills.test.ts passes already-resolved skills directly to runSubprocess(); it cannot catch this startup-snapshot failure. Please add a task-spawn regression with a newly discovered agent/skill and a stale parent session.skills, asserting the child actually receives the new skill content. Without the new branch this test should fail (the child silently runs without the skill).
  • packages/coding-agent/CHANGELOG.md:9 — should-fix — changelog attribution: This new [Unreleased] entry omits the PR link and contributor credit required for external contributions ([#15723](https://github.com/can1357/oh-my-pi/pull/15723) by [@shyamsivakumar](https://github.com/shyamsivakumar)). Please add them to this line.

@roboomp

roboomp commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

packages/coding-agent/src/task/structured-subagent.ts:718

should-fix — regression coverage: runStructuredSubagent() now refreshes only when an autoload name is absent, but the existing test/task/autoload-skills.test.ts passes already-resolved skills directly to runSubprocess(); it cannot catch this startup-snapshot failure. Please add a task-spawn regression with a newly discovered agent/skill and a stale parent session.skills, asserting the child actually receives the new skill content. Without the new branch this test should fail (the child silently runs without the skill).

@roboomp

roboomp commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

packages/coding-agent/CHANGELOG.md:9

should-fix — changelog attribution: This new [Unreleased] entry omits the PR link and contributor credit required for external contributions ([#15723](https://github.com/can1357/oh-my-pi/pull/15723) by [@shyamsivakumar](https://github.com/shyamsivakumar)). Please add them to this line.

…session started

Spawns through runStructuredSubagent with a parent whose skill list predates
the skill, and asserts the child receives the SKILL.md body. Fails without the
refresh in structured-subagent.ts.

@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: 5cb2b581a4

ℹ️ 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".

if (!names?.length || !session.refreshSkills) return;
const known = new Set((session.skills ?? []).map(skill => skill.name));
if (names.every(name => known.has(name))) return;
await session.refreshSkills();

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 Refresh inherited skills for nested agent spawns

When the caller is itself a task agent and adds a skill before spawning a nested agent, this call is a no-op: executor.ts:4420 creates every child with skills: options.skills, and sdk.ts:4611 consequently sets skillsReloadable to false, so AgentSession.refreshSkills() never reruns discovery. The subsequent resolveAutoloadSkills still reads the child's startup snapshot and silently drops the newly added skill, even though nested spawns are enabled by the default recursion depth; preserve reloadability for inherited child snapshots (or provide a forced rediscovery path) before relying on this call.

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: 62cabfd10d

ℹ️ 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 +527 to +529
const known = new Set((session.skills ?? []).map(skill => skill.name));
if (names.every(name => known.has(name))) return;
await session.refreshSkills();

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 Coalesce concurrent autoload refreshes per session

When an RPC/ACP batch or parallel task calls this helper immediately after a skill is added, every spawn can read the same stale session.skills snapshot and enter refreshSkills() before the first call completes. TaskTool.#runSyncSpawns starts rows concurrently (bounded by task.maxConcurrency, which defaults to 32), while SessionTools.refreshSkills() performs a full capability scan and queues a serialized base-system-prompt rebuild, so one batch can issue up to 32 scans and 32 serial rebuilds and leave its final children waiting behind all of them. Coalesce the in-flight refresh per parent session and re-check the requested names after awaiting it.

Useful? React with 👍 / 👎.

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

Labels

agent Agent runtime planning and orchestration fix review:p1 triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants