You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A message can invoke at most one skill. #549 applies the first entry in custom_content.skills and tells the user the rest were ignored ("Only one skill can be invoked per message…").
That limit is not a policy anyone wanted — it falls out of the mechanism. The injector turns the pick into exactly one synthetic read_skill call and result, and SyntheticToolCallInjector emits one pair per injector.
Real requests need more than one skill at a time:
"Review this PR with my review checklist and write it up in my report style."
"Use my SQL style guide and my chart conventions for this dashboard."
Today the user has to split the request into two messages, or pick one skill and describe the other in words — which lands them back on the model's discretion, the thing invocation exists to remove.
What is the feature you are proposing to solve the problem?
Let one message invoke several skills, and apply all of them to that message.
Expected behaviour
A message can invoke more than one skill, and every invoked skill is applied to it.
The order the skills reach the model is deterministic and follows the order the user picked them.
The conversation-wide cap (SKILL_INVOCATION_MAX_SKILLS) still holds and is still spent newest-first, so the skills invoked on the message being answered are never the ones dropped.
A message invoking one skill, or none, behaves exactly as today.
Still a preview feature.
To decide first — a design doc under docs/designs/, before any code:
Do we still need synthetic read_skill pairs? The alternative is an instruction: tell the model that the user's message may name skills and that it must read each one before answering. That is the path the model already uses to pick a skill by description, and it needs no injector, no multi-pair support and no fixed insertion slot. Against it: the model can still skip a skill, which is what Invoke user skills from a chat message (phase 1) #549 set out to prevent. Decide deterministic-but-mechanical versus simple-but-model-dependent, and say why — the answer decides whether item 2 exists at all.
If synthetic: how do several pairs get injected?SyntheticToolCallInjector emits a single call/result pair and places it in a fixed slot after the first user message. N pairs for one message means touching shared orchestration used by every other injector, so it may be worth its own task rather than a line item here.
Two invoked skills that share a manifest name. With several picks per message this stops being exotic. DialSkillResolver's name dedup currently keeps the oldest and drops the rest, so the second skill silently fails to load. Resolved properly by Resolve skill name collisions across predefined, app and user skills #568.
Dependencies
DIAL Chat: the / picker must allow more than one skill per message.
Out of scope: loading the user's whole skill catalogue through Core dependencies (#569); resolving name collisions across predefined, app and user skills (#568); invoking the app's own skills (#550).
What alternatives have you considered?
Keep one skill per message and let users split the request across turns: the current state. It breaks a single intent into two, and the second turn's skill is not in context when the first one's work is done.
Let the user invoke one skill and describe the others in words: puts the model back in charge of the skills the user explicitly chose.
Concatenate the invoked skills into a single synthetic result to keep the one-pair mechanism: avoids touching the shared injector, but fakes one read_skill call as the source of several manifests, so the history no longer reflects what was read — and nothing ties a bundled-file read back to the right skill.
QuickApps version
latest
What is the problem this feature will solve?
A message can invoke at most one skill. #549 applies the first entry in
custom_content.skillsand tells the user the rest were ignored ("Only one skill can be invoked per message…").That limit is not a policy anyone wanted — it falls out of the mechanism. The injector turns the pick into exactly one synthetic
read_skillcall and result, andSyntheticToolCallInjectoremits one pair per injector.Real requests need more than one skill at a time:
Today the user has to split the request into two messages, or pick one skill and describe the other in words — which lands them back on the model's discretion, the thing invocation exists to remove.
What is the feature you are proposing to solve the problem?
Let one message invoke several skills, and apply all of them to that message.
Expected behaviour
SKILL_INVOCATION_MAX_SKILLS) still holds and is still spent newest-first, so the skills invoked on the message being answered are never the ones dropped.To decide first — a design doc under
docs/designs/, before any code:read_skillpairs? The alternative is an instruction: tell the model that the user's message may name skills and that it must read each one before answering. That is the path the model already uses to pick a skill by description, and it needs no injector, no multi-pair support and no fixed insertion slot. Against it: the model can still skip a skill, which is what Invoke user skills from a chat message (phase 1) #549 set out to prevent. Decide deterministic-but-mechanical versus simple-but-model-dependent, and say why — the answer decides whether item 2 exists at all.SyntheticToolCallInjectoremits a single call/result pair and places it in a fixed slot after the first user message. N pairs for one message means touching shared orchestration used by every other injector, so it may be worth its own task rather than a line item here.DialSkillResolver's name dedup currently keeps the oldest and drops the rest, so the second skill silently fails to load. Resolved properly by Resolve skill name collisions across predefined, app and user skills #568.Dependencies
/picker must allow more than one skill per message.Builds on: #549 (closed). Phase 1a design:
docs/designs/skill_invocation.md.Out of scope: loading the user's whole skill catalogue through Core dependencies (#569); resolving name collisions across predefined, app and user skills (#568); invoking the app's own skills (#550).
What alternatives have you considered?
read_skillcall as the source of several manifests, so the history no longer reflects what was read — and nothing ties a bundled-file read back to the right skill.