fix(web): address the second review round on context provenance
- An empty replacement catalog is a real catalog: `renderCatalogUpdate()` publishes zero entries when the last skill disappears, and falling back would hide that every earlier name was retired. - The opaque fallback keeps a `form` declaration this version cannot present. It is the one place a newer or foreign log's declared shape would otherwise vanish from the UI entirely, since the row marker is also absent there. - An instruction change with an unrecognized `action` disqualifies the record. The action decides the word the row shows, so an unknown one would be presented as loaded or updated. - The catalog list bounds itself and reports the withheld count. Entry count is unbounded and the scrollport bounds height, not node count. - A catalog message keeps content blocks this version does not know, instead of dropping model-visible content the extensible union may carry. - `core.md` defines `ContextFormed`, the interface actually carrying the optional field, beside `ContextForm`. - The superseded-in-part bullet states the affected clauses as one rule rather than enumerating them; two rounds of enumeration each missed some, which is the shape being fragile rather than the list being wrong. - The note records the one migration case that does not self-heal: an old-format catalog as the only one, with an empty current view, leaves a stale catalog nothing replaces.
This commit is contained in:
@@ -10,7 +10,7 @@ Requires `ctx.agents`, `ctx.tools`, and `ctx.skills` (`inject: ['agents', 'tools
|
||||
|
||||
At every `agent/step`, the plugin calls `ctx.skills.snapshot()` for the calling session's cwd, forwards the step abort signal to discovery, applies exact `skill` tool visibility, and renders the ordered `name` and `description` entries. When no prior catalog exists and that view is non-empty, it injects an initial durable user-role `<system-reminder>` before the request. Catalog messages contain only those summaries; skill bodies, paths, sources, providers, and `whenToUse` hints remain outside the catalog.
|
||||
|
||||
Every catalog message carries the `skill-catalog` source: a `catalog`-form context whose `entries` record exactly the `name` and `description` pairs it published, plus `update` on a replacement. The digest covers those durable entries, not the rendered prose, so the surrounding `<system-reminder>` framing — written for the model — cannot decide whether a republish is needed, and a consumer presenting the list never re-parses the `<available_skills>` block. The plugin scans durable session events backwards without copying them and derives the comparison baseline from the newest visible `skill-catalog` message. When the digest changes, `agent.inject()` records a durable user-role message containing the complete replacement catalog; an empty replacement explicitly retires earlier names. If no catalog remains visible but a recognizable historical catalog exists, compaction hid it and the next complete observation re-establishes the current catalog. An incomplete provider snapshot emits nothing and preserves the last-good model view for retry on the next step. If no prior catalog exists and the current view is empty, no tombstone is necessary.
|
||||
Every catalog message carries the `skill-catalog` source: a `catalog`-form context whose `entries` record exactly the `name` and `description` pairs it published, plus `update` on a replacement. The digest covers those durable entries, not the rendered prose, so the surrounding `<system-reminder>` framing — written for the model — cannot decide whether a republish is needed, and a consumer presenting the list never re-parses the `<available_skills>` block. The plugin scans durable session events backwards without copying them and derives the comparison baseline from the newest visible `skill-catalog` message it can read; an unreadable record is skipped like any foreign one. When the digest changes, `agent.inject()` records a durable user-role message containing the complete replacement catalog; an empty replacement explicitly retires earlier names. If no catalog remains visible but a recognizable historical catalog exists, compaction hid it and the next complete observation re-establishes the current catalog. An incomplete provider snapshot emits nothing and preserves the last-good model view for retry on the next step. If no prior catalog exists and the current view is empty, no tombstone is necessary.
|
||||
|
||||
The catalog is omitted when no model-invocable skills are initially available, and also when that agent's tool view restricts away the shipped `skill` tool or resolves a same-name scoped shadow instead. Visibility changes participate in the digest, keeping prompt guidance, model-visible schema, and executable dispatch aligned.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user