attachserve

package
v1.125.4 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package attachserve resolves a prompt's attached resources (#1013) into the form each serving surface needs: MCP content items appended to a prompts/get result, and a JSON summary carried by manage_prompt use.

It exists as its own package because it is the one place that needs both pkg/prompt (the attachment links) and pkg/resource (the material, its permissions, and its blobs), and both the MCP prompt layer and the REST attachment handler consume it. Putting it in either of those packages would point a dependency edge the wrong way.

The resolver never fails a prompt. A prompt whose attachment is unreadable, deleted, or unfetchable still serves: the material is reported as unavailable, missing, or unreadable, and the prompt text is unaffected. A procedure that has lost its template is still a procedure, and telling the agent the template is gone is strictly better than refusing to answer.

Index

Constants

View Source
const DefaultInlineLimit = 64 * 1024

DefaultInlineLimit caps how many bytes of a text attachment are embedded directly in a served prompt. Above it the attachment becomes a resource link the client can read on demand.

64 KiB is chosen to match the largest reference material that is still plausibly worth spending prompt context on unconditionally; a report template or checklist is far below it, a full data extract is far above.

Variables

This section is empty.

Functions

func AudienceNote added in v1.123.0

func AudienceNote(p *prompt.Prompt, c *script.Contract) string

AudienceNote states what a reference means for the people this prompt serves, or "" when every reader of the prompt is the script's owner.

It exists because the mismatch is invisible from the authoring side: the author sees their own automation resolve perfectly, while every other reader of a shared prompt receives a note saying part of the procedure was unavailable. Saying so where the reference is made is the difference between a prompt whose author knows what it serves and one that quietly serves less than it reads.

func Content

func Content(items []Resolved) []mcp.Content

Content renders resolved attachments as MCP prompt-message content: embedded resources carry the full text, linked resources carry a resource_link the client can read, and anything the caller cannot reach is summarized in a single trailing note.

The framing text is deliberately directive. An agent that receives a template alongside a procedure must fill that template rather than invent its own formatting, and the only place to say so is here, next to the material.

func ScopeOf

ScopeOf projects a resource onto the fields the scope rule needs. A resource names exactly one audience, so its id set is one element — or none for a global resource, which names no audience because it reaches everyone.

func ScriptContent added in v1.121.0

func ScriptContent(items []ResolvedScript) []mcp.Content

ScriptContent renders resolved references as MCP prompt-message content: one text block framing the automations, each resolved contract, and a trailing note counting anything the caller did not receive.

It is text rather than embedded resources because a script is not a file: what the agent needs is the contract and the instruction to run it. The framing is deliberately directive — an agent holding a procedure that names an automation must run that automation rather than re-derive its output through a conversation, which is the entire point of the feature.

func ScriptSummary added in v1.121.0

func ScriptSummary(items []ResolvedScript) []map[string]any

ScriptSummary renders resolved references for the manage_prompt use provenance block, so an agent can state exactly which automations it received. Unavailable entries carry their reason and nothing else.

func Summary

func Summary(items []Resolved) []map[string]any

Summary renders resolved attachments for the manage_prompt use provenance block, so an agent can state exactly what materials it received. Unavailable entries carry their reason and nothing else.

Types

type Availability

type Availability string

Availability describes whether a prompt's attached material reached the caller, and if not, why.

const (
	// AvailableEmbedded means the full contents are inline in the result.
	AvailableEmbedded Availability = "embedded"
	// AvailableLinked means the caller received a resource link and must read
	// the resource to get its contents (too large to inline, or binary).
	AvailableLinked Availability = "linked"
	// UnavailableForbidden means the attachment exists but this caller cannot
	// read it. Nothing identifying is disclosed alongside it, not even the
	// resource id: the caller has no repair action, and an id would be an
	// existence probe.
	UnavailableForbidden Availability = "unavailable"
	// UnavailableMissing means the resource was deleted after being attached.
	UnavailableMissing Availability = "missing"
	// UnavailableUnreadable means the resource could not be read. When its
	// metadata resolved and only the blob fetch failed, the link is served in
	// place of the contents; when the metadata read itself failed, nothing is
	// known about it and it is counted among the undelivered materials.
	UnavailableUnreadable Availability = "unreadable"
)

type BlobReader

type BlobReader interface {
	GetObject(ctx context.Context, bucket, key string) (body []byte, contentType string, err error)
}

BlobReader reads a resource's stored bytes. Satisfied by resource.S3Client.

type Deps

type Deps struct {
	Attachments prompt.AttachmentStore
	Resources   resource.Store
	Blobs       BlobReader
	Bucket      string

	// InlineLimit overrides DefaultInlineLimit when positive.
	InlineLimit int
}

Deps carries the collaborators the resolver needs. Attachments and Resources are required; a nil Blobs (or empty Bucket) degrades every text attachment to a link rather than failing, which is the correct behavior for a database-only deployment with no blob backend.

type Resolved

type Resolved struct {
	// ResourceID is always set, even when the resource is missing, because it
	// is what an author needs in order to repair a broken link.
	ResourceID string
	// Availability records the outcome. Every other field except ResourceID is
	// empty when it is UnavailableForbidden or UnavailableMissing: an
	// attachment the caller cannot read must not disclose its name, its
	// description, or its size.
	Availability Availability

	URI         string
	DisplayName string
	Description string
	MIMEType    string
	SizeBytes   int64

	// Text holds the contents when Availability is AvailableEmbedded.
	Text string
}

Resolved is one attachment after lookup, permission check, and (when the material is inlined) blob read.

type ResolvedScript added in v1.121.0

type ResolvedScript struct {
	// Reference is always set, even when the script is gone, because it is what
	// an author needs in order to repair a broken link.
	Reference string
	// Availability records the outcome, reusing the resource vocabulary:
	// AvailableEmbedded means the contract is inline below, and the unavailable
	// values mean the caller received nothing but the reason.
	Availability Availability
	// Contract is the resolved contract, set only when Availability is
	// AvailableEmbedded. A caller who may not see the script gets nothing here:
	// a reference must not become a channel for reading a script's name,
	// parameters, or schedule.
	Contract *script.Contract
}

ResolvedScript is one referenced script after lookup and the visibility check.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver resolves prompt attachments for a caller.

func New

func New(deps Deps) *Resolver

New builds a resolver. A nil result is a valid zero-attachment resolver, so callers need no nil checks at every serving site.

func (*Resolver) CheckPromotion

func (r *Resolver) CheckPromotion(ctx context.Context, promptID, targetScope string, targetPersonas []string) error

CheckPromotion reports whether a prompt's current attachments would still satisfy the scope rule at the target scope. It is the gate the promotion request and approval paths call, and it fails closed: a store error blocks the promotion rather than letting it through unchecked.

func (*Resolver) Resolve

func (r *Resolver) Resolve(ctx context.Context, promptID string, claims resource.Claims) []Resolved

Resolve returns a prompt's attachments in authored order, each evaluated for this caller. It returns nil for a prompt with no attachments, and nil rather than an error when the attachment store read fails: a store outage must not take down prompt serving.

func (*Resolver) Scopes

func (r *Resolver) Scopes(ctx context.Context, promptID string) ([]prompt.AttachmentScope, error)

Scopes returns the scope of every resource a prompt attaches, for the authoring-time rule in prompt.CheckAttachScope. It is deliberately caller-independent: the rule asks how widely a resource is visible, not whether one particular reader can see it.

A resource that no longer exists is skipped rather than reported: a broken link cannot violate a scope rule, and blocking a promotion on it would freeze the prompt against every edit until someone detached a link the portal already flags. Any other read failure does block, because an unknown scope is not a safe scope.

type ScriptAttachRequest added in v1.121.0

type ScriptAttachRequest struct {
	// Prompt is the prompt gaining the reference, read for the audience the
	// note reports on.
	Prompt *prompt.Prompt
	// Ref is the script reference or bare id the caller supplied.
	Ref string
	// CallerEmail identifies the author, who must be able to see the script
	// they are referencing: a script is its owner's, so referencing one is
	// something its owner does.
	CallerEmail string
	// CallerIsAdmin lifts that requirement, as administrative authority lifts
	// every other script rule.
	CallerIsAdmin bool
}

ScriptAttachRequest is one request to reference a script from a prompt.

type ScriptDeps added in v1.121.0

type ScriptDeps struct {
	Attachments prompt.ScriptAttachmentStore
	Scripts     ScriptReader
}

ScriptDeps carries the collaborators the script resolver needs: the links and the contracts they resolve to. Both are required; a deployment missing either serves prompts with no referenced scripts rather than failing.

type ScriptReader added in v1.121.0

type ScriptReader interface {
	Contract(ctx context.Context, id string) (*script.Contract, error)
}

ScriptReader resolves one script's contract by id. It is the half of script.Searcher this package needs: serving a prompt reads contracts and never ranks. The concrete PostgreSQL script store satisfies it.

type ScriptResolver added in v1.121.0

type ScriptResolver struct {
	// contains filtered or unexported fields
}

ScriptResolver resolves a prompt's referenced scripts (#1289) into the form each serving surface needs: MCP content appended to a prompts/get result, and a JSON summary carried by manage_prompt use.

Like the resource resolver, it never fails a prompt. A reference whose script was deleted, or that this caller cannot see, is reported as unavailable and the prompt still serves: a procedure that has lost one of its automations is still a procedure, and saying so is strictly better than refusing to answer.

func NewScripts added in v1.121.0

func NewScripts(deps ScriptDeps) *ScriptResolver

NewScripts builds a script resolver. A nil result is a valid zero-attachment resolver, so callers need no nil checks at every serving site.

func (*ScriptResolver) Attach added in v1.121.0

Attach references a script from a prompt.

The one rule is that the caller can see what they are referencing. A wider prompt is not refused: a reference resolves for the script's owner only, and a prompt that also serves other people is a normal thing to write — the automation is simply not part of what those readers receive. AudienceNote states that where the caller can act on it, at the moment they attach, and it is returned so the surface that took the request can show it.

func (*ScriptResolver) Detach added in v1.121.0

func (r *ScriptResolver) Detach(ctx context.Context, promptID, ref string) error

Detach removes one script reference from a prompt, returning prompt.ErrScriptAttachmentNotFound when the prompt does not reference it. It applies no scope rule: dropping a reference can only narrow what a prompt carries.

func (*ScriptResolver) Resolve added in v1.121.0

func (r *ScriptResolver) Resolve(ctx context.Context, promptID, email string) []ResolvedScript

Resolve returns a prompt's referenced scripts in authored order, each evaluated for the caller identified by email. It returns nil when the prompt references none, and nil rather than an error when the link read fails: a store outage must not take down prompt serving.

A script is one person's, so a reference resolves for its owner and for nobody else. A prompt served to a wider audience still serves — every other reader is told an automation was referenced and is out of their reach, which is what AudienceNote warns its author about at the moment they attach it.

Jump to

Keyboard shortcuts

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