docs/design/learn-video-input.md
/learn/learn can create a project skill from text, files, directories, and URLs.
Today every URL is delegated to web_fetch. For a tutorial video URL, that
only exposes the surrounding web page; it does not give the model the video
stream. A model that supports video input therefore cannot use its native
video understanding when the user asks /learn to distill a tutorial.
learnCommand returns a submit_prompt action whose content is the string
produced by buildLearnSkillPrompt. The prompt tells the main model to use
web_fetch for URLs and to write one SKILL.md below
.qwen/skills/learned-skill-<name>/.
The command result already accepts PartListUnion. The OpenAI-compatible
content converter already maps video fileData to an OpenAI video_url, and
Qwen OAuth uses that converter. Effective model modalities are available from
Config.getEffectiveInputModalities().
When the first token passed to /learn is a supported local video path or
direct video-file URL:
Parse the first token as the video source. Treat the remaining text as an optional learning focus.
Require the active model to advertise modalities.video=true and the
active generator to use the OpenAI-compatible path (openai or
qwen-oauth).
If either requirement fails, return an error without submitting a model turn or writing a skill.
For a local video, attach it through the existing workspace-aware file
reader as inline video data. For a direct video URL, submit a video
fileData part.
Submit the video with a video-specific skill-distillation prompt.
The main model writes exactly one learned skill plus a provenance reference:
.qwen/skills/learned-skill-<name>/
├── SKILL.md
└── references/
└── source.md
All non-video inputs retain the existing /learn path.
The first release recognizes only unambiguous native video sources:
.mp4, .webm, .mov, or .m4v.mp4, .webm, .mov, or .m4vThe source must be the first whitespace-delimited token. This keeps parsing deterministic and leaves all remaining text available as a natural-language focus. Arbitrary webpages are not treated as videos.
Local files use the existing workspace boundary, ignore rules, MIME detection,
and 10 MB encoded-data limit. .mp4 uses video/mp4; other direct-file
extensions use their corresponding video MIME type. Direct remote URLs are
passed to the active model provider without a Qwen Code download.
YouTube watch pages are not video files. They are detected and rejected with
guidance to download the video and pass the local file. This is deliberate:
the RESOURCE2SKILL paper uses a resource connector before video sampling, and
the qwen3.5-omni-plus E2E showed that treating a YouTube page URL as an OpenAI
video_url did not return a provider result. A downloader is outside this
release.
The video prompt preserves the existing learned-skill naming and collision rules and adds the following requirements:
when_to_use in YAML frontmatter so it is visible before SkillTool loads
the body.references/source.md with the source, requested focus, and a
timestamped evidence map.source-grounded, not execution-verified.allowedTools, hooks, a model override, or other permission
grants.The existing main-agent writing flow is retained. This change does not add a separate distillation agent or a new tool.
Unsupported video capability is rejected before submit_prompt:
Provider limits, inaccessible URLs, excessive video duration, and other remote media errors are surfaced from the model request. There is no download, transcript, key-frame, or text-only fallback in this release.
Local paths that are missing, outside the workspace, ignored, not recognized as video, or above the existing inline-data limit are rejected before a model turn. YouTube pages are also rejected before submission.
packages/core/src/memory/learn-skill-agent.tspackages/core/src/memory/learn-skill-agent.test.tspackages/cli/src/ui/commands/learn-command.tspackages/cli/src/ui/commands/learn-command.test.tsNo changes are required in SkillManager, SkillTool, read_file, the OpenAI
converter, or settings schemas.
This release does not add:
None block the initial implementation. Direct-video provider limits will be documented through E2E results rather than hidden behind an unverified fallback.
SKILL.md and references/source.md, then a new session must use
that skill to create a working HTML/CSS demo.video_url is not accepted as a
passing ingestion test.