Documentation
¶
Overview ¶
Package artifact implements parsing, validation, and model-facing rendering of odek.artifact-ref/v1 references carried inside odek.tool-result/v1 envelopes (see docs/EXTENSIONS.md).
An artifact ref points at a file produced by an extension (MCP) server whose full output is too large or too binary for the model context. Refs are validated fail-closed against the server's configured artifact roots, and artifact content is NEVER read into the model context — the model sees only the compact envelope text plus per-artifact metadata lines (id, media type, size, short hash prefix, summary). Raw absolute paths are never rendered.
Index ¶
Constants ¶
const ( // SchemaToolResult names the odek tool-result envelope: a JSON text // content item with a compact model-facing "text" plus out-of-band // artifact references. SchemaToolResult = "odek.tool-result/v1" // SchemaArtifactRef names a single artifact reference inside a // tool-result envelope. SchemaArtifactRef = "odek.artifact-ref/v1" )
Schema names carried in the "schema" field of structured payloads. These are the canonical definitions; internal/mcpclient aliases them so the extension contract has a single source of truth.
const MaxArtifactBytes int64 = 64 << 20
MaxArtifactBytes is the absolute ceiling on a single artifact file that Validate will process (stat or hash). Enforced at Stat time so a server that supplies sha256 but omits size_bytes cannot force an unbounded streaming hash (see Validate).
const MaxArtifactsPerEnvelope = 64
MaxArtifactsPerEnvelope caps how many artifact refs one tool-result envelope may carry. Every validated ref becomes a model-facing metadata line appended AFTER the envelope text has passed the server's max_result_chars cap, so the count must itself be bounded.
Variables ¶
This section is empty.
Functions ¶
func CountRendered ¶
CountRendered returns the number of artifact metadata lines in a string produced by Render — 0 for plain-text results. Used by the runtime event stream to report artifact_count without re-parsing the envelope.
func Render ¶
Render produces the model-facing form of a validated envelope: the compact text plus one metadata line per artifact (id, media type, size, short hash prefix, summary). It NEVER includes the resolved filesystem path or any artifact content. Server-controlled strings are flattened to a single line each so one artifact cannot forge additional metadata lines.
func Validate ¶
Validate checks an artifact ref fail-closed against the configured artifact roots and returns the resolved (symlink-evaluated) absolute path of the artifact file. The returned path is for local bookkeeping only (e.g. a future event log); it must never be rendered into the model-facing result.
Every violation is an error — there is no partial acceptance:
- ref.Schema must match SchemaArtifactRef exactly
- id, uri, and media_type are required
- roots must be non-empty (empty roots ⇒ every ref is rejected)
- uri must be a file:// URI with no host, query, or fragment
- the path must be absolute and clean (no "..", "//", or "." elements; percent-encoded traversal is decoded before this check)
- the path must exist and, after filepath.EvalSymlinks, stay inside one of the roots (symlink escapes are rejected)
- the target must be a regular file
- the file must be at most MaxArtifactBytes (checked before hashing)
- size_bytes, when present, must equal the real file size
- sha256, when present, must be a lowercase hex digest matching the file
The artifact content is only ever read to compute the verification hash; it is never returned to the caller.
Types ¶
type Envelope ¶
type Envelope struct {
Schema string `json:"schema"`
Text string `json:"text"`
Artifacts []Ref `json:"artifacts,omitempty"`
}
Envelope is the odek.tool-result/v1 envelope shape. Unknown fields are ignored per the contract's additive rule.
func ParseEnvelope ¶
ParseEnvelope detects and parses an odek.tool-result/v1 envelope carried as the text of a tool result.
A result that is not a JSON object, or whose "schema" field does not match SchemaToolResult exactly, is a plain text result: ParseEnvelope returns (nil, nil) and the caller forwards the text unchanged. A result that claims the envelope schema but is structurally malformed (e.g. "artifacts" is not an array of objects) fails closed with an error — the schema marker is a claim the payload must back up.
type Ref ¶
type Ref struct {
Schema string `json:"schema"`
ID string `json:"id"`
URI string `json:"uri"`
MediaType string `json:"media_type"`
SHA256 string `json:"sha256,omitempty"`
SizeBytes *int64 `json:"size_bytes,omitempty"`
Summary string `json:"summary,omitempty"`
}
Ref is a single odek.artifact-ref/v1 object. Unknown fields are ignored per the contract's additive rule. SizeBytes is a pointer so "absent" is distinguishable from an explicit zero (verification is skipped when absent, enforced when present).