fix(skill): normalize invocation policy

This commit is contained in:
Yichen Jiang
2026-07-28 17:55:49 +08:00
parent 09d14e344f
commit babb8f1496
28 changed files with 123 additions and 105 deletions

View File

@@ -1937,7 +1937,7 @@ The concrete provider retains pi-tui, focus, and terminal lifecycle state. Plugi
abstract openOverlay(request: TuiOverlayRequest): TuiOverlaySession
```
Source: [`packages/ui/tui/src/index.ts:191`](../../packages/ui/tui/src/index.ts)
Source: [`packages/ui/tui/src/index.ts:192`](../../packages/ui/tui/src/index.ts)
## `ctx.userInteraction` — `UserInteractionService`

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/core-data-structures/skills.md
skills.md: e641ffd578e52dcda8a1c191123c097333c6f238
skills.zh.md: c5de8201c4e762438d15f12b169556543b6758b1
skills.md: 850aa589055f5e611619868ef6d05b3165f917a4
skills.zh.md: da36f301b6a8b38d83a190f759f9f2ed82b8ce4b

View File

@@ -62,15 +62,15 @@ type SkillSource = 'project-dsh' | 'project-agents' | 'runtime' | 'user-dsh' | '
## Summaries, candidates, and complete definitions
`SkillSummary` is the registry's invocation-neutral summary shape. Consumers choose which entries and fields to render; the model session catalog uses only model-invocable `name` and `description`, never the body or absolute file path. `SkillInvocationPolicy` keeps the two independent invocation controls typed without turning arbitrary frontmatter into the domain model.
`SkillSummary` is the registry's invocation-neutral summary shape. Consumers choose which entries and fields to render; the model session catalog uses only model-invocable `name` and `description`, never the body or absolute file path. `SkillInvocationPolicy` normalizes the two independent invocation controls into positive booleans without turning arbitrary frontmatter into the domain model.
```ts type-equiv
/** Invocation controls shared by skill discovery consumers. */
interface SkillInvocationPolicy {
/** Whether model-facing catalogs and loaders exclude this skill. */
readonly disableModelInvocation?: boolean
/** Whether model-facing catalogs and loaders include this skill. */
readonly modelInvocable: boolean
/** Whether human-facing command catalogs and loaders include this skill. */
readonly userInvocable?: boolean
readonly userInvocable: boolean
}
```
@@ -94,7 +94,7 @@ interface SkillSummary {
}
```
`ctx.skills.list()` preserves all four policy combinations. `isModelInvocable(skill)` excludes only `disableModelInvocation: true`, while `isUserInvocable(skill)` excludes only `userInvocable: false`; missing fields permit both surfaces. A model-only skill sets `userInvocable: false`, a user-only skill sets `disableModelInvocation: true`, and setting both restrictive values keeps the skill available only through trusted `ctx.skills.get()` callers. The local provider reads these values from the exact kebab-case frontmatter keys `disable-model-invocation` and `user-invocable`.
`ctx.skills.list()` preserves all four policy combinations. An absent `invocation` object permits both surfaces; when present, both booleans are required. `isModelInvocable(skill)` and `isUserInvocable(skill)` read the corresponding positive field. A model-only skill sets `{ modelInvocable: true, userInvocable: false }`, a user-only skill sets `{ modelInvocable: false, userInvocable: true }`, and setting both fields to `false` keeps the skill available only through trusted `ctx.skills.get()` callers. The local provider reads the exact kebab-case frontmatter keys `disable-model-invocation` and `user-invocable`, applies their defaults, and projects them into this normalized policy.
`SkillCandidate` is the provider-to-registry shape. `locator` is opaque provider state; the registry only stores it and gives it back to the winning provider's `get()`.

View File

@@ -62,15 +62,15 @@ type SkillSource = 'project-dsh' | 'project-agents' | 'runtime' | 'user-dsh' | '
## 摘要、候选项与完整定义
`SkillSummary` 是注册表中与调用策略无关的摘要形状。消费方自行选择渲染哪些条目和字段;模型会话目录仅使用模型可调用 skill 的 `name` 和 `description`,从不使用正文或绝对文件路径。`SkillInvocationPolicy` 使两个独立调用控制保持类型化,而不会把任意 frontmatter 纳入领域模型。
`SkillSummary` 是注册表中与调用策略无关的摘要形状。消费方自行选择渲染哪些条目和字段;模型会话目录仅使用模型可调用 skill 的 `name` 和 `description`,从不使用正文或绝对文件路径。`SkillInvocationPolicy` 两个独立调用控制规范化为正向布尔值,而不会把任意 frontmatter 纳入领域模型。
```ts type-equiv
/** Invocation controls shared by skill discovery consumers. */
interface SkillInvocationPolicy {
/** Whether model-facing catalogs and loaders exclude this skill. */
readonly disableModelInvocation?: boolean
/** Whether model-facing catalogs and loaders include this skill. */
readonly modelInvocable: boolean
/** Whether human-facing command catalogs and loaders include this skill. */
readonly userInvocable?: boolean
readonly userInvocable: boolean
}
```
@@ -94,7 +94,7 @@ interface SkillSummary {
}
```
`ctx.skills.list()` 保留全部四种策略组合。`isModelInvocable(skill)` 仅排除 `disableModelInvocation: true``isUserInvocable(skill)` 仅排除 `userInvocable: false`;字段缺失时两个接口均允许调用。仅供模型调用的 skill 设置 `userInvocable: false`,仅供用户调用的 skill 设置 `disableModelInvocation: true`同时设置两个限制值后,该 skill 只能由受信的 `ctx.skills.get()` 调用方获取。本地提供方名称完全匹配的 kebab-case frontmatter 键 `disable-model-invocation` 和 `user-invocable` 读取这些值
`ctx.skills.list()` 保留全部四种策略组合。缺少 `invocation` 对象时两个接口均允许调用;该对象存在时,两个布尔字段都为必填。`isModelInvocable(skill)` 和 `isUserInvocable(skill)` 分别读取对应的正向字段。仅供模型调用的 skill 设置 `{ modelInvocable: true, userInvocable: false }`,仅供用户调用的 skill 设置 `{ modelInvocable: false, userInvocable: true }`两个字段均设为 `false` 后,该 skill 只能由受信的 `ctx.skills.get()` 调用方获取。本地提供方读取名称完全匹配的 kebab-case frontmatter 键 `disable-model-invocation` 和 `user-invocable`,应用其默认值,再将其投影到这个规范化策略中
`SkillCandidate` 是提供方到注册表的形状。`locator` 是提供方的不透明状态;注册表只存储它并在调用获胜提供方的 `get()` 时传回。