feat(web): split context injection into producer-declared forms
Injected context reached the transcript as one anonymous shape whose expanded body was the whole message serialized as inline JSON, so the escaping collapsed the only readable part — the model-facing prose — into a single line. `MessageSource` gains an optional producer-declared `form`, a small semantic vocabulary of information shapes independent of `kind`: kind says who produced the context, form says what shape it is, so several producers may share one presentation. Two values ship. `instructions` (workspace-context) lists the reconciled files above their text and keeps the `<system-reminder>` framing verbatim, because the framing is part of what the model read. `catalog` moves dsh-tool-skill off the shared plugin kind onto a `skill-catalog` source carrying the published name/description entries, and the body lists those instead of re-parsing `<available_skills>` out of the prose. Catalog identity moves with it: the republish digest now covers the durable entries, deleting the text-slicing that recovered them from a logged message. Everything else renders the opaque body — the model-facing text with its real line breaks, then the remaining provenance as fields. That is the documented default, not a leftover: a resumed, forked, or foreign log must render whether or not its producer is mounted here, which is why the classification lives in the durable source rather than a client-side table keyed by producer.
This commit is contained in:
@@ -14,6 +14,7 @@ const checkpoint = {
|
||||
content: [],
|
||||
source: { kind: 'plugin', plugin: 'compact' },
|
||||
provenance: { role: 'inject', label: 'compact' },
|
||||
form: null,
|
||||
} as ConversationNode
|
||||
|
||||
const abandoned = {
|
||||
|
||||
Reference in New Issue
Block a user