fix(agent-core-v2): rescan agent profile catalog when a dispatch lookup misses - #2340
fix(agent-core-v2): rescan agent profile catalog when a dispatch lookup misses#2340lostforwurdz wants to merge 1 commit into
Conversation
…up misses Long-lived sessions (e.g. hosted by kimi web) scan agent file directories once at session materialization, so agent Markdown files written afterward can never be dispatched: the Agent tool, AgentSwarm tool, and swarm spawn path all fail with "Unknown agent type" until the server restarts. Add getProfileOrReload(), a small lookup helper in the sessionAgentProfileCatalog domain: on a miss it calls the catalog's existing (previously unwired) reload() once — deduped across concurrent misses — and retries before the caller's original error path applies. The three dispatch sites read the catalog live, so a rescan is visible to existing sessions immediately; the happy path is unchanged.
🦋 Changeset detectedLatest commit: 27c4342 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 27c4342c54
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| }); | ||
| reloadInFlight.set(catalog, reload); | ||
| } | ||
| await reload; |
There was a problem hiding this comment.
Honor aborts after a miss-triggered catalog reload
When a foreground Agent/AgentSwarm dispatch is interrupted while this miss-triggered reload is scanning, the callers have already linked their abort signal but do not re-check it after await getProfileOrReload; execution can therefore continue into lifecycle.create and emit a spawned subagent before the later subagents.run observes the aborted signal. Please make this helper abortable or have each caller call signal.throwIfAborted() immediately after the reload-backed lookup.
Useful? React with 👍 / 👎.
Related Issue
Resolve #2339
Problem
See linked issue. In short: long-lived sessions hosted by
kimi webscan agent file directories once at session materialization, so agent Markdown files written afterward can never be dispatched —Unknown agent type: "<name>"— until the server restarts.kimi -pand the v2 TUI/reloaddo not have this problem, so behavior is inconsistent across entry points.What changed
SessionAgentProfileCatalogService.reload()already implements exactly the rescan we need (reload all sources, remerge, fireonDidChange), but it had no production callers. Rather than adding a new mechanism, this PR wires it in at the point of need:getProfileOrReload()helper in thesessionAgentProfileCatalogdomain:await catalog.ready→catalog.get(name)→ on a miss, onecatalog.reload()(deduped across concurrent misses via an in-flightWeakMapentry) → retry the lookup. Still-missing names returnundefinedand the caller throws exactly as before.agentTool.ts), the AgentSwarm tool (agentSwarmTool.ts), and the swarm spawn path (sessionSwarmService.ts). All three read the catalog live, so a rescan is visible to existing sessions on the very next dispatch.Why this approach fits: it reuses the existing reload path instead of introducing fs watchers (lifecycle, debounce, cross-platform event semantics) or a new kap-server route. The happy path is unchanged; the only cost is one extra directory scan on a genuine miss, which previously was a guaranteed error anyway.
Tests: three new cases in
sessionAgentProfileCatalog.test.ts— rescan picks up a file written after the initial scan, a genuinely unknown name still returnsundefinedafter rescanning, and a cached hit skips the rescan while concurrent misses share a single reload. Fullagent-core-v2suite: 4201/4201 passing,typecheckandlint:domainclean. Also verified end-to-end against a locally builtkimi web: session materialized, probe agent file written afterward, dispatch from that same session succeeds.Docs:
customization/agents.md(en + zh) now notes that long-lived sessions rescan on dispatch of an unknown profile.Checklist
gen-changesetsskill, or this PR needs no changeset. (changeset included: patch on@moonshot-ai/agent-core-v2and@moonshot-ai/kimi-code)gen-docsskill, or this PR needs no doc update. (docs updated:docs/en/customization/agents.md,docs/zh/customization/agents.md)