bytedance / bytedance/deer-flow

Shared composer skill feed: agent-scoped catalog + a reserved-name source for the /context compact alias

Open
#5,259 1 comment 0 reactions 0 assignees View on GitHub
needs-triage
Dominant language
Python
Stars
82.4k
Forks
11.4k
Avg merge
2d 8h
Merged PRs (30d)
295

Description

**Context**: surfaced during the #5102 review (skill picker entry). Two catalog/collision gaps live in the *shared* composer surfaces, pre-date that PR, and deliberately do not belong in it — both fixes change behavior for every composer path (slash suggestions and the picker alike), so they need their own change.

## 1. The skill feed is not agent-scoped

`useSkills()` (`frontend/src/components/workspace/input-box.tsx:363`) returns the unfiltered `GET /api/skills` catalog. On a custom-agent chat whose `agent.skills` is an explicit allowlist — especially `[]` — the slash suggestions and the picker both offer skills that agent cannot use. Verified today on both surfaces (they share the one feed; a picker-only filter would diverge the two surfaces for the same name).

**Proposed shape**: scope the catalog at the shared feed — e.g. a `useSkills({ agentId })`-style parameter or a selector that intersects with the active agent's allowlist when one is set — so every consumer (slash suggestions at input-box.tsx:1300, the picker's `getSelectableSkills`, anything future) derives from one source.

## 2. A skill named `context` collides with the `/context compact` alias

`parseCompactCommand` accepts `/^(?:compact|context\s+compact)\s*$/i` (`frontend/src/components/workspace/input-box-helpers.ts:265`), but `context` is in neither `RESERVED_SLASH_SKILL_NAMES` nor `COMPOSER_BUILTIN_COMMAND_NAMES` (`frontend/src/core/skills/slash.ts`). Verified today, entirely on the pre-existing slash path:

- `getMatchingSkillSuggestions([skill("context")], "context", [])` → offers it (`kind: "skill"`);
- `getInputSubmitAction({ text: "/context compact", fileCount: 0, status: "idle" })` → `{ kind: "compact" }` — picking the skill and typing `compact` as the task silently runs context compaction instead of the skill.

**Proposed shape**: fix it at the parse/reserved-name contract, not at either suggestion surface — e.g. teach the shared exclusion source (or `parseCompactCommand` itself) that `context` is unreachable when followed by `compact`, mirroring how `compact` is already owned by `COMPOSER_BUILTIN_COMMAND_NAMES`. `core/skills/slash.ts` is already the contract-pinned module mirrored by the backend via `contracts/slash_skill_contract.json`, so the reserved-name change should consider whether the fixture needs to move too.

Happy to take either or both as a follow-up PR once the picker lands.

Contributor guide

Open the contributing guide

Research direction

Start with useSkills() in frontend/src/components/workspace/input-box.tsx and its shared consumers, including the slash suggestions and getSelectableSkills, then trace how the active agent allowlist reaches the feed. Read parseCompactCommand in frontend/src/components/workspace/input-box-helpers.ts and the reserved-name contract in frontend/src/core/skills/slash.ts, checking contracts/slash_skill_contract.json. Done means both surfaces show only allowed skills and a context skill cannot conflict with /context compact.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.