Help us shape the future of Go! Take the 2026 Go Developer Survey

native

package module
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

The built-in file and shell tools of the native harness: read, write, edit, glob, grep, and bash, all rooted at one jail directory (plan 2026-09-26 I.3). Every path argument is relative to the root; an absolute path or one that escapes the root is refused.

Package native is the in-process harness: a provider-agnostic tool loop with the same Session and Event model as the CLI drivers (plan 2026-09-26 I). A consumer supplies a Model from a provider module, tools, skills, a permission policy, and credentials; the package drives the turn loop and emits agentwire events.

The root agent-wire module stays free of provider SDKs. The provider adapters live in native/provider/*, one nested module each.

Index

Constants

View Source
const DefaultMaxTurns = 20

DefaultMaxTurns bounds one prompt when Config.MaxTurns is unset.

Variables

View Source
var ErrNotFound = errors.New("native: no stored session")

ErrNotFound is what a Store.Load returns for a session it has no log for.

Functions

This section is empty.

Types

type Annotations

type Annotations struct {
	ReadOnly    bool
	Destructive bool
	Idempotent  bool
	OpenWorld   bool
	// Kind is the coarse class the permission policy and the UI read.
	Kind agentwire.ToolKind
}

Annotations describe one tool for the permission policy and the UI, in the shape of the MCP tool annotations.

type ApprovalRequest

type ApprovalRequest struct {
	CallID string
	Spec   ToolSpec
	Input  json.RawMessage
}

ApprovalRequest is one tool call awaiting a decision.

type Approver

type Approver interface {
	Approve(ctx context.Context, r ApprovalRequest) (agentwire.Decision, error)
}

Approver decides one tool call. The loop calls it before every mutating call, and before any call when the policy says ask.

type ApproverFunc

type ApproverFunc func(ctx context.Context, r ApprovalRequest) (agentwire.Decision, error)

ApproverFunc adapts a function to Approver.

func (ApproverFunc) Approve

func (f ApproverFunc) Approve(ctx context.Context, r ApprovalRequest) (agentwire.Decision, error)

type Compactor

type Compactor interface {
	Compact(ctx context.Context, m Model, msgs []Message) ([]Message, error)
}

Compactor folds a full message list into one that fits the context window. The loop runs it before a model call when the list has grown past the configured token budget.

func SummaryCompactor

func SummaryCompactor(keepLast int) Compactor

SummaryCompactor keeps the last keepLast messages verbatim and replaces everything before them with one summary the model itself writes. It is the trebi compact rule: trigger around 60% of the context budget (plan 2026-09-26 I.5).

type CompactorFunc

type CompactorFunc func(ctx context.Context, m Model, msgs []Message) ([]Message, error)

CompactorFunc adapts a function to Compactor.

func (CompactorFunc) Compact

func (f CompactorFunc) Compact(ctx context.Context, m Model, msgs []Message) ([]Message, error)

type Config

type Config struct {
	// NewModel builds the Model of one session from the credentials and the
	// model name. A provider module supplies the constructor.
	NewModel func(c agentwire.Credentials, model string) (Model, error)
	// Credentials resolves the provider credentials of one session. It is
	// called per session; StartRequest.Credentials wins when set. The
	// library never reads env or secrets for it.
	Credentials func() (agentwire.Credentials, error)
	// ToolSets are the consumer's own tools, next to the session's MCP
	// servers and the built-in file tools.
	ToolSets []ToolSet
	// ToolSetFuncs open one ToolSet per session. Use them for tools that
	// cannot be shared, such as an in-process MCP transport pair.
	ToolSetFuncs []func(ctx context.Context) (ToolSet, error)
	// BuiltinTools roots the built-in read, write, edit, glob, grep, and
	// bash tools at StartRequest.WorkingDir.
	BuiltinTools bool
	// MaxFileBytes caps one read or write of the built-in file tools.
	// Zero uses a 10 MiB default.
	MaxFileBytes int64
	// Store persists the message log. Nil keeps no log and resume never
	// finds anything.
	Store Store
	// Compactor folds the message list when it outgrows the budget. Nil
	// disables compaction.
	Compactor Compactor
	// ContextTokens is the compaction budget.
	ContextTokens int
	// MaxTurns bounds one prompt. Zero uses DefaultMaxTurns. A cap ends the
	// turn with the max_turn_requests reason.
	MaxTurns int
	// MaxOutputTokens bounds one model call. Zero uses the provider
	// default.
	MaxOutputTokens int
	// BeforeCall runs before every model call. A non-nil error fails the
	// turn; a daily token cap goes here.
	BeforeCall func(ctx context.Context, sessionID string) error
	// AfterCall runs after every model call with its usage.
	AfterCall func(ctx context.Context, sessionID string, u Usage)
	// Approver replaces the default policy approver.
	Approver Approver
}

Config is the consumer-side configuration of the native driver. The consumer supplies tools, MCP servers, skills, a permission policy, and provider credentials, as it does for Claude or Codex (plan 2026-09-26 I).

type Driver

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

Driver drives the in-process native harness. It implements agentwire.Driver and agentwire.Detector.

func NewDriver

func NewDriver(cfg Config) *Driver

NewDriver builds the native driver.

func (*Driver) Close

func (d *Driver) Close() error

Close closes the driver and every MCP tool set it opened.

func (*Driver) Detect

func (d *Driver) Detect(_ context.Context) (agentwire.Detection, error)

Detect implements agentwire.Detector: native is always in-process and supported; the auth state comes from the credential resolver and the model name.

func (*Driver) Name

func (d *Driver) Name() string

Name implements agentwire.Driver.

func (*Driver) Resume

func (d *Driver) Resume(ctx context.Context, req agentwire.StartRequest) (agentwire.Session, error)

func (*Driver) Start

func (d *Driver) Start(ctx context.Context, req agentwire.StartRequest) (agentwire.Session, error)

Start opens one native session. Resume is Start: the message log decides what the model sees.

type FilePart

type FilePart struct {
	MediaType string `json:"media_type,omitempty"`
	Data      []byte `json:"data,omitempty"`
	URL       string `json:"url,omitempty"`
}

FilePart is one attachment. Exactly one of Data or URL is set.

type Finish

type Finish struct {
	Reason FinishReason
	Raw    string
	Usage  Usage
}

Finish is the terminal stream part.

type FinishReason

type FinishReason string

FinishReason unifies vendor stop reasons. Raw keeps the vendor string.

const (
	FinishStop          FinishReason = "stop"
	FinishLength        FinishReason = "length"
	FinishToolCalls     FinishReason = "tool_calls"
	FinishContentFilter FinishReason = "content_filter"
	FinishRefusal       FinishReason = "refusal"
	FinishError         FinishReason = "error"
	FinishOther         FinishReason = "other"
)

type MemoryStore

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

MemoryStore is an in-process Store, for tests and ephemeral sessions.

func NewMemoryStore

func NewMemoryStore() *MemoryStore

func (*MemoryStore) Append

func (m *MemoryStore) Append(_ context.Context, sessionID string, msgs ...Message) error

func (*MemoryStore) Load

func (m *MemoryStore) Load(_ context.Context, sessionID string) ([]Message, error)

func (*MemoryStore) Replace

func (m *MemoryStore) Replace(_ context.Context, sessionID string, msgs []Message) error

type Message

type Message struct {
	Role  Role   `json:"role"`
	Parts []Part `json:"parts"`
}

Message is one provider-neutral conversation entry. The loop persists these verbatim, so a resume replays exactly, including provider metadata such as thinking signatures.

type Model

type Model interface {
	// Name is the model identifier the driver reports on init.
	Name() string
	// Stream runs one model call and yields the response as stream parts.
	// The sequence must yield exactly one StreamFinish.
	Stream(ctx context.Context, req Request) Seq[StreamPart]
}

Model is the provider abstraction a session drives. Implementations live in native/provider/*.

type Part

type Part struct {
	Text       *TextPart      `json:"text,omitempty"`
	File       *FilePart      `json:"file,omitempty"`
	Reasoning  *ReasoningPart `json:"reasoning,omitempty"`
	ToolCall   *ToolCall      `json:"tool_call,omitempty"`
	ToolResult *ToolResult    `json:"tool_result,omitempty"`
}

Part holds exactly one of the payload fields. A nil-valued union keeps JSON round-trips honest: one kind per Part.

type PolicyApprover

type PolicyApprover struct {
	Policy agentwire.PermissionPolicy
	// Emit surfaces one permission request to the consumer. It must return
	// the channel the decision arrives on. Nil means the policy alone
	// decides and everything else is denied.
	Emit func(ctx context.Context, r ApprovalRequest) (wait func(ctx context.Context) (agentwire.Decision, error), cancel func())
}

PolicyApprover is the default Approver. It asks the session's PermissionPolicy first; a policy that does not answer emits one EventPermission on out and blocks on the returned decision func until the consumer answers or the context ends (plan 2026-09-26 I.5).

func (PolicyApprover) Approve

func (a PolicyApprover) Approve(ctx context.Context, r ApprovalRequest) (agentwire.Decision, error)

type ReasoningPart

type ReasoningPart struct {
	Text         string          `json:"text"`
	ProviderMeta json.RawMessage `json:"provider_meta,omitempty"`
}

ReasoningPart is one reasoning block. ProviderMeta carries opaque provider state, such as an Anthropic thinking signature, so a replay is valid.

type Request

type Request struct {
	// System is the system prompt.
	System string
	// Messages is the full conversation, tool results included.
	Messages []Message
	// Tools is the callable surface for this call.
	Tools []ToolSpec
	// ToolChoice steers tool use. The zero value is Auto.
	ToolChoice ToolChoice
	// MaxOutputTokens bounds one response. Zero means the provider default.
	MaxOutputTokens int
	// Effort is low | medium | high | max. The provider maps it onto its own
	// thinking budget or reasoning effort.
	Effort string
	// ProviderOptions carries provider-specific extensions. The provider
	// modules document their keys.
	ProviderOptions map[string]json.RawMessage
}

Request is one model call.

type Role

type Role string

Role labels one message side of the conversation.

const (
	RoleUser      Role = "user"
	RoleAssistant Role = "assistant"
	RoleTool      Role = "tool"
)

type Seq

type Seq[T any] = iter.Seq2[T, error]

Seq is an alias so provider modules need no iter import for the signature.

type SkillCatalog

type SkillCatalog struct {
	Skills []SkillMeta
}

SkillCatalog is the progressive-disclosure surface: the prompt carries the catalog only, and the activate_skill tool loads the body on demand (agentskills.io, plan 2026-09-26 I.5).

func LoadSkills

func LoadSkills(skills []agentwire.Skill) (SkillCatalog, error)

LoadSkills reads the frontmatter of every skill.

func (SkillCatalog) ActivateTool

func (c SkillCatalog) ActivateTool() Tool

ActivateTool returns the activate_skill tool: it loads one SKILL.md body and lists the skill directory's resources.

func (SkillCatalog) PreApproved

func (c SkillCatalog) PreApproved() []string

PreApproved lists the tools of every skill's allowed-tools frontmatter.

func (SkillCatalog) Prompt

func (c SkillCatalog) Prompt() string

Prompt renders the <available_skills> block for the system prompt.

type SkillMeta

type SkillMeta struct {
	Name string
	// Description is the frontmatter description.
	Description string
	// Dir is the absolute skill directory.
	Dir string
	// AllowedTools lists tools the skill's frontmatter pre-approves.
	AllowedTools []string
}

SkillMeta is one catalog entry: enough for the model to decide whether to activate the skill.

type Store

type Store interface {
	// Load returns the stored messages. ErrNotFound means the store has no
	// log for the session and the caller starts fresh.
	Load(ctx context.Context, sessionID string) ([]Message, error)
	Append(ctx context.Context, sessionID string, msgs ...Message) error
	Replace(ctx context.Context, sessionID string, msgs []Message) error
}

Store persists the provider-neutral message log of one session. The loop appends after every model and tool step, so a resume replays exactly.

func FileStore

func FileStore(dir string) Store

FileStore is the NDJSON message log under dir/<session>.messages.jsonl. It reads the trebi legacy llm.Message shape as well, so stored native sessions survive the migration (plan 2026-09-26 I.7 step 6).

type Stream

type Stream = Seq[StreamPart]

Stream is the sequence type of Model.Stream. It yields StreamParts and at most one error, after which the sequence ends.

type StreamKind

type StreamKind int

StreamKind labels one streaming part.

const (
	StreamTextDelta StreamKind = iota
	StreamReasoningDelta
	StreamToolInputStart
	StreamToolInputDelta
	StreamToolCallDone
	StreamFinish
)

type StreamPart

type StreamPart struct {
	Kind StreamKind
	// ID is the tool-call id for the tool parts.
	ID string
	// Delta is the text of a text or reasoning delta, or one JSON fragment
	// of a tool input.
	Delta string
	// Call is the complete call on StreamToolCallDone.
	Call *ToolCall
	// Finish terminates the stream.
	Finish *Finish
}

StreamPart is one element of a Model.Stream sequence.

type TextPart

type TextPart struct {
	Text string `json:"text"`
}

TextPart is plain text.

type Tool

type Tool interface {
	Spec() ToolSpec
	Call(ctx context.Context, input json.RawMessage) (ToolResult, error)
}

Tool is one callable tool. Call returns an error only for an infrastructure failure the loop must surface; a failure the model should see is a ToolResult with IsError.

func NewFunc

func NewFunc[In, Out any](spec ToolSpec, fn func(context.Context, In) (Out, error)) Tool

NewFunc builds a Tool from a typed function. The input schema is inferred from In via reflection: exported fields with a json tag, required every field that is not a pointer.

type ToolCall

type ToolCall struct {
	ID    string          `json:"id"`
	Name  string          `json:"name"`
	Input json.RawMessage `json:"input,omitempty"`
}

ToolCall is one model-requested tool invocation.

type ToolChoice

type ToolChoice struct {
	Mode ToolChoiceMode
	// Name names the tool when Mode is ToolNamed.
	Name string
}

ToolChoice is the tool-use steering of one call.

type ToolChoiceMode

type ToolChoiceMode int

ToolChoiceMode says how the provider may pick tools.

const (
	ToolAuto ToolChoiceMode = iota
	ToolNone
	ToolRequired
	ToolNamed
)

type ToolResult

type ToolResult struct {
	CallID  string `json:"call_id"`
	Name    string `json:"name,omitempty"`
	Content []Part `json:"content"`
	IsError bool   `json:"is_error,omitempty"`
}

ToolResult is one tool answer fed back to the model.

type ToolSet

type ToolSet interface {
	Name() string
	Tools(ctx context.Context) ([]Tool, error)
	Close() error
}

ToolSet is a named group of tools that shares one lifecycle. MCP servers, the built-in file tools, and a consumer's own tools are all ToolSets.

func MCPSessionToolSet

func MCPSessionToolSet(name string, cs *mcp.ClientSession) ToolSet

MCPSessionToolSet wraps a connected client session, for an in-process server over mcp.NewInMemoryTransports.

func MCPToolSet

func MCPToolSet(ctx context.Context, srv agentwire.MCPServer, client *mcp.Implementation) (ToolSet, error)

MCPToolSet connects one agentwire.MCPServer and exposes its tools. A server with Command runs over stdio; a server with URL speaks streamable HTTP (plan 2026-09-26 I.5).

func StaticTools

func StaticTools(name string, tools ...Tool) ToolSet

StaticTools wraps fixed tools as a ToolSet.

type ToolSpec

type ToolSpec struct {
	Name        string
	Title       string
	Description string
	// InputSchema is a JSON Schema object.
	InputSchema json.RawMessage
	Annotations Annotations
}

ToolSpec is the model-visible description of one tool.

type Usage

type Usage struct {
	Input      int64
	Output     int64
	CacheRead  int64
	CacheWrite int64
	Reasoning  int64
}

Usage is token accounting for one model call.

Directories

Path Synopsis
provider
anthropic module
openai module

Jump to

Keyboard shortcuts

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