refactor(skill): canonicalize invocation policy
This commit is contained in:
@@ -1241,7 +1241,7 @@ export interface Config {
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/skill/skill/src/index.ts:139`](../packages/skill/skill/src/index.ts)
|
||||
Source: [`packages/skill/skill/src/index.ts:144`](../packages/skill/skill/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-skill-local`
|
||||
|
||||
|
||||
@@ -1645,7 +1645,7 @@ registerProvider(provider: SkillProvider): () => void
|
||||
* Register a borrowed readonly runtime skill. Project entries outrank runtime entries, which
|
||||
* outrank user entries. Same-name runtime entries are first-wins; a duplicate logs a warning and
|
||||
* receives a no-op disposer so it cannot remove the winner.
|
||||
* @param skill - the complete skill definition to expose for discovery.
|
||||
* @param skill - the skill definition input; omitted invocation and provider fields receive defaults.
|
||||
* @returns the exact Cordis effect disposer, preserving composite teardown order and invalidating caches.
|
||||
*/
|
||||
register(skill: SkillRegistration): () => void
|
||||
@@ -1673,7 +1673,7 @@ async get(name: string, options: SkillLookupOptions = {}): Promise<SkillDefiniti
|
||||
|
||||
Types: [SkillDefinition](../core-data-structures/skills.md) · [SkillLookupOptions](../core-data-structures/skills.md) · [SkillProvider](../core-data-structures/skills.md) · [SkillRegistration](../core-data-structures/skills.md) · [SkillSummary](../core-data-structures/skills.md)
|
||||
|
||||
Source: [`packages/skill/skill/src/index.ts:167`](../../packages/skill/skill/src/index.ts)
|
||||
Source: [`packages/skill/skill/src/index.ts:172`](../../packages/skill/skill/src/index.ts)
|
||||
|
||||
## `ctx.spillStore` — `SpillStore` (abstract seam)
|
||||
|
||||
|
||||
@@ -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: 850aa589055f5e611619868ef6d05b3165f917a4
|
||||
skills.zh.md: da36f301b6a8b38d83a190f759f9f2ed82b8ce4b
|
||||
skills.md: 2524606ad058d5cbf81e287a7001777b4a125aaf
|
||||
skills.zh.md: 7bc2d2165172da46bde0cfe0b9a1be279ea8af32
|
||||
|
||||
@@ -62,7 +62,7 @@ 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` normalizes the two independent invocation controls into positive booleans 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, and every resolved summary, candidate, and definition carries it without turning arbitrary frontmatter into the domain model.
|
||||
|
||||
```ts type-equiv
|
||||
/** Invocation controls shared by skill discovery consumers. */
|
||||
@@ -83,8 +83,8 @@ interface SkillSummary {
|
||||
readonly description: string
|
||||
/** Optional extra routing guidance. */
|
||||
readonly whenToUse?: string
|
||||
/** Optional model and user invocation controls. */
|
||||
readonly invocation?: SkillInvocationPolicy
|
||||
/** Resolved model and user invocation controls. */
|
||||
readonly invocation: SkillInvocationPolicy
|
||||
/** Discovery source that produced this winning skill. */
|
||||
readonly source: SkillSource
|
||||
/** Provider that owns this skill body. */
|
||||
@@ -94,7 +94,7 @@ interface SkillSummary {
|
||||
}
|
||||
```
|
||||
|
||||
`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.
|
||||
`ctx.skills.list()` preserves all four policy combinations. `isModelInvocable(skill)` and `isUserInvocable(skill)` read the corresponding required 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`, defaults omitted fields to `true`, and projects every parsed skill 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()`.
|
||||
|
||||
@@ -134,11 +134,16 @@ interface SkillDefinition extends SkillSummary {
|
||||
}
|
||||
```
|
||||
|
||||
Runtime skills use the same complete shape and participate in the same first-wins collection order. The returned disposer removes the contribution and invalidates discovery caches.
|
||||
Runtime skill inputs may omit invocation controls and the provider label. The registry resolves both defaults once, then uses the same complete definition shape and first-wins collection order as providers. The returned disposer removes the contribution and invalidates discovery caches.
|
||||
|
||||
```ts type-equiv
|
||||
/** Runtime skill contribution accepted by `ctx.skills.register()`. */
|
||||
type SkillRegistration = Omit<SkillDefinition, 'provider'> & { readonly provider?: string }
|
||||
type SkillRegistration = Omit<SkillDefinition, 'invocation' | 'provider'> & {
|
||||
/** Invocation controls; omission permits both model and user surfaces. */
|
||||
readonly invocation?: SkillInvocationPolicy
|
||||
/** Provider label; omission uses the registry-owned runtime provider. */
|
||||
readonly provider?: string
|
||||
}
|
||||
```
|
||||
|
||||
## Lookup and configuration
|
||||
|
||||
@@ -62,7 +62,7 @@ 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. */
|
||||
@@ -83,8 +83,8 @@ interface SkillSummary {
|
||||
readonly description: string
|
||||
/** Optional extra routing guidance. */
|
||||
readonly whenToUse?: string
|
||||
/** Optional model and user invocation controls. */
|
||||
readonly invocation?: SkillInvocationPolicy
|
||||
/** Resolved model and user invocation controls. */
|
||||
readonly invocation: SkillInvocationPolicy
|
||||
/** Discovery source that produced this winning skill. */
|
||||
readonly source: SkillSource
|
||||
/** Provider that owns this skill body. */
|
||||
@@ -94,7 +94,7 @@ interface SkillSummary {
|
||||
}
|
||||
```
|
||||
|
||||
`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`,应用其默认值,再将其投影到这个规范化策略中。
|
||||
`ctx.skills.list()` 保留全部四种策略组合。`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`,将省略的字段默认为 `true`,并为每个解析出的 skill 生成这个规范化策略。
|
||||
|
||||
`SkillCandidate` 是提供方到注册表的形状。`locator` 是提供方的不透明状态;注册表只存储它并在调用获胜提供方的 `get()` 时传回。
|
||||
|
||||
@@ -134,11 +134,16 @@ interface SkillDefinition extends SkillSummary {
|
||||
}
|
||||
```
|
||||
|
||||
运行时 skill 使用相同的完整形状,参与相同的先到先得收集顺序。返回的 disposer 移除该贡献并使发现缓存失效。
|
||||
运行时 skill 输入可以省略调用控制和提供方标签。注册表会一次性补全这两项默认值,随后使用与提供方相同的完整定义形状和先到先得收集顺序。返回的 disposer 移除该贡献并使发现缓存失效。
|
||||
|
||||
```ts type-equiv
|
||||
/** Runtime skill contribution accepted by `ctx.skills.register()`. */
|
||||
type SkillRegistration = Omit<SkillDefinition, 'provider'> & { readonly provider?: string }
|
||||
type SkillRegistration = Omit<SkillDefinition, 'invocation' | 'provider'> & {
|
||||
/** Invocation controls; omission permits both model and user surfaces. */
|
||||
readonly invocation?: SkillInvocationPolicy
|
||||
/** Provider label; omission uses the registry-owned runtime provider. */
|
||||
readonly provider?: string
|
||||
}
|
||||
```
|
||||
|
||||
## 查找与配置
|
||||
|
||||
Reference in New Issue
Block a user