ctx

package
v0.6.13 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const MigrationSQL = `` /* 2218-byte string literal not displayed */
View Source
const MigrationSQL009 = `` /* 305-byte string literal not displayed */

Migration 009: project_id column for per-project isolation on existing databases.

Variables

This section is empty.

Functions

func FilePrelude added in v0.4.0

func FilePrelude(language, path string) string

FilePrelude returns the language-specific snippet that exposes the file's content to user code via well-known variables. The user code is then concatenated after this prelude and executed.

FILE_PATH      — absolute path to the file (string).
FILE_CONTENT   — the file's contents read as text (string).

For shell, FILE_PATH is exported and FILE_CONTENT is loaded into the variable.

Types

type BatchCommand

type BatchCommand struct {
	Label    string `json:"label"`
	Command  string `json:"command"`
	Language string `json:"language"`
}

type BatchExecutor

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

BatchExecutor runs multiple sandbox commands sequentially, indexes combined output, and optionally searches the indexed content.

func NewBatchExecutor

func NewBatchExecutor(sandbox *Sandbox, indexer *Indexer, searcher *Searcher, logger *slog.Logger) *BatchExecutor

NewBatchExecutor creates a BatchExecutor. If logger is nil, slog.Default() is used.

func (*BatchExecutor) ExecuteBatch

func (be *BatchExecutor) ExecuteBatch(ctx context.Context, commands []BatchCommand, queries []string, sessionID string, intent string, projectID string, concurrency int) (*BatchResult, error)

ExecuteBatch runs commands and indexes all combined output, optionally searching the indexed content.

concurrency=1 (or <=0) runs commands sequentially. concurrency>1 fans them out across that many workers (capped at maxBatchConcurrency=8). Order of `results` always matches input order regardless of concurrency.

A failing command (non-zero exit, timeout) is recorded in results but does NOT abort the batch.

If queries is non-empty, each query is run against the Searcher with MaxResults=5 and results are deduplicated by ChunkID.

If the combined output exceeds 5 KB and intent is non-empty, all output is indexed but only search results matching intent terms are returned.

type BatchResult

type BatchResult struct {
	Results       []ExecuteResult       `json:"results"`
	SearchResults []ContentSearchResult `json:"search_results,omitempty"`
	SourceID      string                `json:"source_id"`
	TotalBytes    int64                 `json:"total_bytes"`
}

type Chunk

type Chunk struct {
	ID          string    `json:"id"`
	SessionID   string    `json:"session_id"`
	ProjectID   string    `json:"project_id"`
	Source      string    `json:"source"`
	Label       string    `json:"label"`
	Content     string    `json:"content"`
	Metadata    string    `json:"metadata,omitempty"`
	ContentType string    `json:"content_type,omitempty"`
	IndexedAt   time.Time `json:"indexed_at"`
	TTLHours    int       `json:"ttl_hours"`
}

type ChunkData

type ChunkData struct {
	Heading string
	Content string
	HasCode bool
}

type Chunker

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

func NewChunker

func NewChunker(maxBytes int) *Chunker

func (*Chunker) Chunk

func (c *Chunker) Chunk(source []byte) []ChunkData

type ContentSearchResult

type ContentSearchResult struct {
	ChunkID string  `json:"chunk_id"`
	Label   string  `json:"label"`
	Source  string  `json:"source"`
	Snippet string  `json:"snippet"`
	Score   float64 `json:"score"`
}

type Evictor

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

Evictor runs periodic TTL expiration and LRU cap enforcement.

func NewEvictor

func NewEvictor(store *Store, db *sql.DB, cfg EvictorConfig, logger *slog.Logger) *Evictor

NewEvictor creates a new Evictor. If logger is nil, uses slog.Default().

func (*Evictor) Close

func (e *Evictor) Close()

Close signals the background goroutine to stop and waits for it to finish. Safe to call multiple times.

func (*Evictor) RunEviction

func (e *Evictor) RunEviction(ctx context.Context) (int, error)

RunEviction performs one eviction cycle: TTL expiration then LRU cap enforcement. Returns the total number of chunks deleted.

func (*Evictor) Start

func (e *Evictor) Start(ctx context.Context)

Start launches the background eviction goroutine.

type EvictorConfig

type EvictorConfig struct {
	TTLDefaultHours  int           // default TTL for new chunks
	LRUCapBytes      int64         // max total bytes for all chunks (0 = unlimited)
	EvictionInterval time.Duration // how often background eviction runs
}

EvictorConfig controls eviction behaviour.

type ExecuteResult

type ExecuteResult struct {
	Stdout    string        `json:"stdout"`
	Stderr    string        `json:"stderr,omitempty"`
	ExitCode  int           `json:"exit_code"`
	Duration  time.Duration `json:"duration"`
	TimedOut  bool          `json:"timed_out"`
	Truncated bool          `json:"truncated"`
}

type FetchBatchEntry added in v0.4.1

type FetchBatchEntry struct {
	URL       string `json:"url"`
	Source    string `json:"source"`
	Bytes     int    `json:"bytes"`
	FetchedAt string `json:"fetched_at"`
	FromCache bool   `json:"from_cache"`
	Error     string `json:"error,omitempty"`
}

type FetchBatchResult added in v0.4.1

type FetchBatchResult struct {
	Entries []FetchBatchEntry `json:"entries"`
}

type FetchRequest added in v0.4.1

type FetchRequest struct {
	URL    string `json:"url"`
	Source string `json:"source,omitempty"`
}

type FetchResult

type FetchResult struct {
	Markdown    string    `json:"markdown"`
	ContentType string    `json:"content_type"`
	URL         string    `json:"url"`
	FetchedAt   time.Time `json:"fetched_at"`
	FromCache   bool      `json:"from_cache"`
}

type Fetcher

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

func NewFetcher

func NewFetcher(timeout, cacheTTL time.Duration, logger *slog.Logger) *Fetcher

func (*Fetcher) ClearCache

func (f *Fetcher) ClearCache()

func (*Fetcher) FetchAndConvert

func (f *Fetcher) FetchAndConvert(ctx context.Context, url string) (*FetchResult, error)

func (*Fetcher) Invalidate added in v0.4.0

func (f *Fetcher) Invalidate(url string)

Invalidate drops the cached entry for url, forcing the next FetchAndConvert call to hit the network.

type Indexer

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

Indexer orchestrates chunking and store insertion with content-hash deduplication.

func NewIndexer

func NewIndexer(store *Store, chunker *Chunker, db *sql.DB, defaultTTL int, logger *slog.Logger) *Indexer

NewIndexer creates an Indexer. If defaultTTL <= 0, 336 (14 days) is used. If logger is nil, slog.Default() is used.

func (*Indexer) IndexContent

func (ix *Indexer) IndexContent(ctx context.Context, content string, source string, label string, sessionID string, contentType string, projectID string) (string, error)

IndexContent chunks markdown content by headings and inserts unique chunks into the store. Returns a sourceGroupID linking all chunks from this indexing operation.

func (*Indexer) IndexRaw

func (ix *Indexer) IndexRaw(ctx context.Context, content string, source string, label string, sessionID string, projectID string) (string, error)

IndexRaw indexes non-markdown content (shell output, etc.) by splitting at newline boundaries. Returns a sourceGroupID linking all chunks from this indexing operation.

type Optimizer

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

Optimizer is the facade that MCP tools call. It composes all internal components (Store, Sandbox, Chunker, Searcher, Indexer, Fetcher, BatchExecutor, Evictor) and exposes a clean public API.

func NewOptimizer

func NewOptimizer(db *sql.DB, cfg config.ContextOptimizerConfig, logger *slog.Logger) (*Optimizer, error)

NewOptimizer creates all internal components, wires them together, and starts the background evictor goroutine.

func (*Optimizer) Close

func (o *Optimizer) Close()

Close stops the background evictor. Safe to call multiple times.

func (*Optimizer) Execute

func (o *Optimizer) Execute(ctx context.Context, code string, language string, timeoutSec int) (*ExecuteResult, error)

Execute runs code in the sandbox. If timeoutSec > 0, a child context with that timeout is created; otherwise the config default is used (already baked into the Sandbox).

func (*Optimizer) ExecuteBatch

func (o *Optimizer) ExecuteBatch(ctx context.Context, commands []BatchCommand, queries []string, intent string, projectID string, concurrency int) (*BatchResult, error)

ExecuteBatch runs multiple commands and optionally searches indexed output. concurrency=1 (default) runs sequentially; concurrency>1 fans out across up to maxBatchConcurrency workers. Order of `Results` is preserved.

func (*Optimizer) ExecuteFile

func (o *Optimizer) ExecuteFile(ctx context.Context, path string, language string, code string) (*ExecuteResult, error)

ExecuteFile runs user code in the sandbox after injecting a language-specific prelude that exposes FILE_PATH (and FILE_CONTENT for languages where reading is idiomatic). The user's code is concatenated after the prelude so it can reference these variables directly without doing its own I/O.

For PHP the prelude is wrapped in <?php tags, so the user code must contain its own <?php opening tag if it expects to write PHP — same constraint as any other PHP CLI runner.

func (*Optimizer) FetchAndIndex

func (o *Optimizer) FetchAndIndex(ctx context.Context, url string, source string, projectID string, force bool) (*FetchResult, error)

FetchAndIndex fetches a URL, converts to markdown, and indexes the content. If force is true, the URL's cache entry is invalidated first.

func (*Optimizer) FetchAndIndexBatch added in v0.4.1

func (o *Optimizer) FetchAndIndexBatch(ctx context.Context, requests []FetchRequest, concurrency int, projectID string, force bool) (*FetchBatchResult, error)

FetchAndIndexBatch fetches multiple URLs, converts each to markdown, and indexes them. concurrency=1 runs sequentially; concurrency>1 fans out across up to maxBatchConcurrency workers. Per-URL failures are reported in the returned entries (Error field) rather than aborting the batch.

func (*Optimizer) IndexContent

func (o *Optimizer) IndexContent(ctx context.Context, content string, source string, label string, contentType string, projectID string) (string, error)

IndexContent chunks markdown content and indexes it. Returns a sourceGroupID.

func (*Optimizer) IndexRaw

func (o *Optimizer) IndexRaw(ctx context.Context, content string, source string, label string, projectID string) (string, error)

IndexRaw indexes non-markdown content. Returns a sourceGroupID.

func (*Optimizer) Search

func (o *Optimizer) Search(ctx context.Context, query string, maxResults int, contentType string, source string, projectID string) ([]ContentSearchResult, error)

Search searches indexed content.

func (*Optimizer) Store

func (o *Optimizer) Store() *Store

Store exposes the underlying Store for session event operations.

type Sandbox

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

func NewSandbox

func NewSandbox(timeout time.Duration, maxOutputBytes int64, workDir string) *Sandbox

func (*Sandbox) Execute

func (s *Sandbox) Execute(parent context.Context, language string, code string) (*ExecuteResult, error)

type SearchOpts

type SearchOpts struct {
	MaxResults  int    `json:"max_results"`
	ContentType string `json:"content_type,omitempty"`
	Source      string `json:"source,omitempty"`
	ProjectID   string `json:"project_id,omitempty"`
}

type Searcher

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

func NewSearcher

func NewSearcher(store chunkSearcher, logger *slog.Logger) *Searcher

func (*Searcher) Search

func (s *Searcher) Search(ctx context.Context, query string, opts SearchOpts) ([]ContentSearchResult, error)

type SessionEvent

type SessionEvent struct {
	ID        string    `json:"id"`
	SessionID string    `json:"session_id"`
	ProjectID string    `json:"project_id"`
	EventType string    `json:"event_type"`
	Priority  int       `json:"priority"`
	ToolName  string    `json:"tool_name,omitempty"`
	Summary   string    `json:"summary,omitempty"`
	Metadata  string    `json:"metadata,omitempty"`
	CreatedAt time.Time `json:"created_at"`
}

type Store

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

Store provides CRUD and FTS5 search for ephemeral content chunks and session events.

func NewStore

func NewStore(db *sql.DB, logger *slog.Logger) *Store

NewStore creates a Store backed by db. If logger is nil, uses slog.Default().

func (*Store) DeleteChunks

func (s *Store) DeleteChunks(ctx context.Context, ids []string) error

DeleteChunks removes chunks by IDs in a single transaction.

func (*Store) DeleteEventsBySession

func (s *Store) DeleteEventsBySession(ctx context.Context, sessionID string) error

DeleteEventsBySession removes all events for a given session.

func (*Store) GetChunk

func (s *Store) GetChunk(ctx context.Context, id string) (*Chunk, error)

GetChunk retrieves a single chunk by ID.

func (*Store) GetChunksBySource

func (s *Store) GetChunksBySource(ctx context.Context, source string) ([]Chunk, error)

GetChunksBySource returns all chunks matching the given source label.

func (*Store) GetExpiredChunkIDs

func (s *Store) GetExpiredChunkIDs(ctx context.Context) ([]string, error)

GetExpiredChunkIDs returns IDs of chunks whose TTL has elapsed.

func (*Store) GetTotalSize

func (s *Store) GetTotalSize(ctx context.Context) (int64, error)

GetTotalSize returns the sum of length(content) across all chunks.

func (*Store) InsertChunk

func (s *Store) InsertChunk(ctx context.Context, chunk *Chunk) error

InsertChunk generates a UUID and inserts chunk into content_chunks.

func (*Store) InsertEvent

func (s *Store) InsertEvent(ctx context.Context, event *SessionEvent) error

InsertEvent generates a UUID and inserts a session event.

func (*Store) PrepareStatements

func (s *Store) PrepareStatements() error

PrepareStatements pre-compiles frequently used queries. Call after migration.

func (*Store) QueryEvents

func (s *Store) QueryEvents(ctx context.Context, sessionID string, limit int) ([]SessionEvent, error)

QueryEvents retrieves events for a session, ordered by created_at DESC.

func (*Store) SearchChunks

func (s *Store) SearchChunks(ctx context.Context, query string, maxResults int, contentType string, source string, projectID string) ([]ContentSearchResult, error)

SearchChunks performs FTS5 trigram search with optional content_type and source filters. User query terms are wrapped in double quotes for trigram matching. BM25 rank (negative) is normalized to a positive score: 1.0 / (1.0 + -rank).

Jump to

Keyboard shortcuts

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