feat(tool-skill): inject user-invoked skills at the pre-step gesture boundary
A whitespace-bounded /name token anywhere in a claimed user message, naming a user-invocable skill in the workspace directory, now injects that skill's renderSkillContent as instructions context appended after every other injection of the step — the same agent/pre-step seam the catalog, workspace instructions, and the runtime snapshot ride. Closed-set matching mirrors the command registry (a miss stays plain prose), only user-source messages are scanned, the policy check runs on the loaded definition, and this is the sole entry point for disable-model-invocation skills. The catalog's no-reload sentence now names the gesture boundary.
This commit is contained in:
@@ -39,7 +39,7 @@ This package owns the `ctx.skills` interface. It does not know whether skills co
|
||||
|
||||
### Shared model-facing rendering
|
||||
|
||||
`renderSkillContent(skill)` renders one loaded skill as the canonical `<skill_content>` block (escaped `name` attribute, resource hints, verbatim body). It is the single truth for both loading paths: `dsh-tool-skill` returns it as the `skill` tool result, and the host's user-explicit `skill.invoke` injects it as a user message, so the model sees one shape regardless of who initiated the load. `escapeText` is exported beside it for consumers embedding prose in the same markup frame. The package also declares the `skill-invocation` `MessageSource` kind ({ name, args? }) that user-explicit injection stamps on its messages — transcript consumers present the invocation from this metadata instead of re-parsing the body.
|
||||
`renderSkillContent(skill)` renders one loaded skill as the canonical `<skill_content>` block (escaped `name` attribute, resource hints, verbatim body). It is the single truth for both loading paths: `dsh-tool-skill` returns it as the `skill` tool result and injects it at the user-explicit gesture boundary, so the model sees one shape regardless of who initiated the load. `escapeText` is exported beside it for consumers embedding prose in the same markup frame. The package also declares the `skill-invocation` `MessageSource` kind ({ name, form: 'instructions' }) that user-explicit injection stamps on its messages — transcript consumers present the invocation from this metadata instead of re-parsing the body.
|
||||
|
||||
`isModelInvocable(skill)` and `isUserInvocable(skill)` read the matching positive field directly. `ctx.skills.get()` remains the trusted, policy-neutral loading primitive, so every user- or model-facing consumer must enforce the predicate that matches its surface before exposing or loading a skill.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user