Documentation
¶
Overview ¶
Package blob stores the binary content amoxtli needs to hand back verbatim — today the images it describes. Indexing makes an image *searchable* (phases 1-3: its description is indexed as text); a blob store makes it *displayable* again, because the description alone cannot be shown to a user, the original file may have moved, and data URIs are stripped from the rendered chunks.
Blobs are content-addressed: the hash of the content is the key, so storing the same bytes twice is a no-op and two documents embedding the same image share one entry. Documents reference them through a stable internal URI (see URI) that survives the markdown rendering.
Index ¶
Constants ¶
const ( URIScheme = "amoxtli" URIHost = "images" )
Scheme and host of the internal blob URIs.
const DefaultMaxBytes int64 = 10 << 20 // 10 MiB
DefaultMaxBytes bounds the size of a single blob. It mirrors the default image size limit of the vision describer: content the model would refuse is not worth storing either.
Variables ¶
var ( // ErrNotFound is returned by Get when no blob carries the given hash. ErrNotFound = errors.New("blob not found") // ErrTooLarge is returned by Put when the content exceeds the store limit. ErrTooLarge = errors.New("blob too large") )
Functions ¶
func URI ¶
URI returns the internal URI referencing a blob, the form written into the markdown of indexed documents.
The scheme is what makes it work end to end: markdown.StripDataURL only strips `data:` destinations, so `amoxtli://images/<hash>` survives the rendering of a chunk. An agent therefore sees the reference right next to the description text and knows what to ask for (see the fetch_image MCP tool).
Types ¶
type Hash ¶
type Hash string
Hash identifies a blob: the hex-encoded sha256 of its content.
func CheckPut ¶
CheckPut validates what every implementation must refuse identically — empty content, missing media type, oversized payload — and returns the hash the content must be stored under. Implementations call it first thing in Put so the conformance suite sees the same behaviour everywhere.
func ComputeHash ¶
ComputeHash returns the hash content will be stored under.
func ParseURI ¶
ParseURI extracts the hash from an internal blob URI. It also accepts a bare hash, so a tool can be lenient about what an agent passes back.
func ScanHashes ¶
ScanHashes extracts every blob hash referenced by an internal URI in the given content. It is how the garbage collector derives the live set: the documents themselves are the source of truth, with no reference table to keep in sync.
type SnapshottedBlob ¶
SnapshottedBlob is the serialized form of a blob in a snapshot.
type Snapshotter ¶
type Snapshotter struct {
// contains filtered or unexported fields
}
Snapshotter turns any Store into a backup.Snapshotable. It is written against the interface rather than against an implementation for a concrete reason: a snapshot taken from a filesystem store restores into a database store and vice versa, which is what makes migrating a workspace between backends possible. For an all-PostgreSQL deployment the server's own SQL backup already covers the blobs table; this snapshot remains useful for portability.
func NewSnapshotter ¶
func NewSnapshotter(store Store) *Snapshotter
NewSnapshotter adapts store to the backup interfaces.
func (*Snapshotter) GenerateSnapshot ¶
func (s *Snapshotter) GenerateSnapshot(ctx context.Context) (io.ReadCloser, error)
GenerateSnapshot implements backup.Snapshotable. Blobs are streamed one at a time: a corpus of images does not fit in memory, and neither should its snapshot.
func (*Snapshotter) RestoreSnapshot ¶
RestoreSnapshot implements backup.Snapshotable. Restoring is additive: blobs are content-addressed, so re-putting an existing one is a no-op and nothing already stored is destroyed.
type Store ¶
type Store interface {
// Put stores the content and returns its hash. It is idempotent: putting
// the same content again is a no-op returning the same hash.
Put(ctx context.Context, mimeType string, data []byte) (Hash, error)
// Get returns the content and metadata of a blob, or ErrNotFound.
Get(ctx context.Context, hash Hash) ([]byte, *Info, error)
// Delete removes the given blobs. Deleting an unknown hash is not an
// error: the caller's intent (that the blob be gone) is satisfied.
Delete(ctx context.Context, hashes ...Hash) error
// List walks every stored blob. Returning an error from fn stops the walk
// and is returned to the caller.
List(ctx context.Context, fn func(Info) error) error
}
Store persists content addressed by the hash of its bytes.
Implementations must be safe for concurrent use.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package fs implements a filesystem-backed blob store, for the local (SQLite) workspaces: content under <dir>/<2 hex>/<hash>, its media type in a <hash>.json sidecar.
|
Package fs implements a filesystem-backed blob store, for the local (SQLite) workspaces: content under <dir>/<2 hex>/<hash>, its media type in a <hash>.json sidecar. |
|
Package gorm implements a database-backed blob store covering SQLite and PostgreSQL with the same code, on the model of ingest/gorm and task/gorm.
|
Package gorm implements a database-backed blob store covering SQLite and PostgreSQL with the same code, on the model of ingest/gorm and task/gorm. |
|
Package testsuite is the conformance suite every blob.Store implementation must pass.
|
Package testsuite is the conformance suite every blob.Store implementation must pass. |