artifact

package
v1.33.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 10 Imported by: 0

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

View Source
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.

View Source
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).

View Source
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

func CountRendered(s string) int

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 RemoveSessionSubtree added in v1.32.0

func RemoveSessionSubtree(root, sessionID string) error

RemoveSessionSubtree removes <root>/<session_id> (the delegate_tasks artifact output of one session). The id is validated against a strict charset first; an invalid id is a silent no-op (nothing matched can exist under the root anyway, and cleanup must never turn into a traversal primitive). Missing subtrees are not an error.

func Render

func Render(env *Envelope) string

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

func Validate(ref Ref, roots []string) (string, error)

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

func ParseEnvelope(text string) (*Envelope, error)

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).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL