diff --git a/.changeset/skill-zod-examples-drop-retired-trigger-phrases.md b/.changeset/skill-zod-examples-drop-retired-trigger-phrases.md new file mode 100644 index 0000000000..a7f93d1b80 --- /dev/null +++ b/.changeset/skill-zod-examples-drop-retired-trigger-phrases.md @@ -0,0 +1,13 @@ +--- +"@objectstack/spec": patch +--- + +**Docs:** `skill.zod.ts`'s two `@example` blocks stop handing the author a retired key that throws on parse (#11026). + +Both TSDoc examples in `packages/spec/src/ai/skill.zod.ts` — the one over `SkillSchema` and the one over `defineSkill` — passed `triggerPhrases`, removed in `@objectstack/spec` 17.0.0 (#3896 audit close-out) and carried as a `retiredKey()` tombstone ~120 lines below the first of them. `defineSkill` calls `SkillSchema.parse()`, so both documented blocks **threw** when run: `invalid_type` at path `triggerPhrases`, expected `never`. A reader copying either block got a refusal on their first move. + +The blocks now demonstrate the tombstone's own prescription instead of contradicting it. That prescription is a **split**, not a rename — routing intent belongs in `triggerConditions` (an AND of context field/operator/value), natural-language intent in `description` / `instructions`, the strings actually put in front of the model — and the `defineSkill` block shows both halves with each named. `tools` is required with no default, so both blocks carry it. Each block also opens with its own `import { defineSkill } from '@objectstack/spec';`, matching the convention the marked SDK examples in `packages/client-react/src` already use, so the block is self-contained as a consumer would resolve it. + +The tombstone and every line of its guidance prose are **unchanged**, verbatim — they were always correct, and they are what the repaired examples now agree with. + +Prose only: no schema shape, no `.describe()` text, no runtime behaviour, no authorable-surface movement, and `check:generated` moves nothing (the generated reference page `content/docs/references/ai/skill.mdx` renders the tombstoned row as `[REMOVED]` and carries neither example). It is graded rather than skipped because the text ships to consumers: the rewritten blocks are present in the built `dist/skill.zod-*.d.ts`, which is what an editor surfaces on hover, and `@objectstack/spec`'s `files` list publishes `src/**/*.zod.ts` so the docblock also travels in the npm tarball as source. diff --git a/packages/spec/src/ai/skill.zod.ts b/packages/spec/src/ai/skill.zod.ts index 796d85450d..fea8bbddd7 100644 --- a/packages/spec/src/ai/skill.zod.ts +++ b/packages/spec/src/ai/skill.zod.ts @@ -247,13 +247,18 @@ export type SkillTriggerCondition = z.input; * * @example * ```ts + * import { defineSkill } from '@objectstack/spec'; + * * const skill = defineSkill({ * name: 'case_management', * label: 'Case Management', * description: 'Handles support case lifecycle', - * instructions: 'Use these tools to create, update, and resolve support cases.', + * // Natural-language intent lives in the strings actually put in front of + * // the model. A skill is never activated by matching a phrase list. + * instructions: + * 'Use these tools to create, update, and resolve support cases. Reach for this ' + * + 'skill when the user wants to open a ticket, chase an existing case, or close one out.', * tools: ['create_case', 'update_case', 'resolve_case', 'query_cases'], - * triggerPhrases: ['create a case', 'open a ticket', 'resolve issue'], * }); * ``` */ @@ -432,14 +437,24 @@ export type SkillParsed = z.infer; * Validates the config at creation time using Zod `.parse()`. * * @example + * Activation is a SPLIT, and this block shows both halves: programmatic + * routing in `triggerConditions`, natural-language intent in + * `description` / `instructions`. + * * ```ts + * import { defineSkill } from '@objectstack/spec'; + * * const skill = defineSkill({ * name: 'order_management', * label: 'Order Management', * description: 'Handles order lifecycle operations', - * instructions: 'Use these tools to manage customer orders.', + * // Half one — natural language, read by the LLM. + * instructions: + * 'Use these tools to manage customer orders. Reach for this skill when the user ' + * + 'wants to place an order, change one, or cancel one.', * tools: ['create_order', 'update_order', 'cancel_order'], - * triggerPhrases: ['place an order', 'cancel my order'], + * // Half two — a programmatic AND of context field/operator/value, + * // evaluated by the cloud agent runtime. * triggerConditions: [ * { field: 'objectName', operator: 'eq', value: 'order' }, * ],