core

package module
v0.10.0 Latest Latest
Warning

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

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

README

core

core is the narrow waist of Scope: the serializable, provider-neutral protocols that every provider implements and every capability module consumes.

It owns protocol values, the minimal calling SPI per modality, and the pure composition around them. It owns no provider SDK, no network backend, no tokenizer vocabulary, no agent control flow, and no telemetry.

Install

go get github.com/Tangerg/scope/core

Packages

Package Owns
chat Chat protocol: Message, Part, Request, Response, Options, tool calls, usage, output format
chatclient Direct chat conveniences: immutable defaults, middleware chain, templates, structured output, tool middleware
chatclient/safeguard Fail-closed input/output screening as chat middleware
embedding Text-to-vector protocol and its Model SPI
embeddingclient Direct embedding conveniences and dimension resolution
image Image-generation protocol
moderation Content-moderation protocol
speech Text-to-speech protocol and its independent Streamer
transcription Audio-to-text protocol
document The canonical Document content value
media The Media container shared by every modality
metadata JSON-safe typed extension values
jsonschema Schema derivation, parsing, and validation
tool Executable tool contract, binding, authorization, registry, typed functions
tokenizer Token counting and encoding capabilities (no vocabulary)
history Conversation history contracts, window projection, middleware
history/inmemory Zero-value-ready in-process history store
vectorstore Semantic indexing and search over Document
vectorstore/filter Metadata-filter expression vocabulary, parser, and visitor
vectorstore/inmemory In-process vector store
modeltest, history/storetest, vectorstore/storetest Reusable contract suites for implementors

Calling a model

Every modality exposes a minimal Model SPI with a single Call. Real streaming is a separate Streamer, so a provider that cannot stream never has to pretend it can.

response, err := model.Call(ctx, &chat.Request{
    Messages: []chat.Message{
        chat.NewUserMessage(chat.NewTextPart("Hello")),
    },
    Options: &chat.Options{Model: "provider-model"},
})

chatclient adds the ordinary-path conveniences — frozen defaults, a middleware chain, prompt templates, and structured output — without changing the SPI. Client is an immutable value, so a configured client is safe to share:

client, err := chatclient.New(model, chatclient.Config{
    Defaults: chat.Options{Model: "provider-model"},
})
if err != nil {
    return err
}

response, err := client.Call(ctx, request)

Client.Output binds one typed output contract, and the same decoder serves both the synchronous and the streaming path:

type Answer struct {
    Summary string `json:"summary"`
}

answer, err := client.Output(chatclient.JSON[Answer]()).Call(ctx, request)

Streaming

Streams are iter.Seq2[*chat.Response, error]. Early break, context cancellation, and first-error termination are part of the contract:

for response, err := range client.Stream(ctx, request) {
    if err != nil {
        return err
    }
    fmt.Print(response.Text())
}

Errors

Every provider-facing modality package exports the same three sentinels, so providers and integrations classify failures identically:

  • ErrInvalidOptions — the caller's options are not usable.
  • ErrInvalidRequest — the request violates the protocol.
  • ErrInvalidResponse — the provider returned something the protocol rejects.

chat extends that triple with its own protocol errors because its wire additionally models tool calls, parts, and usage. Classify with errors.Is; never match on message text.

Implementing a provider

Implement the modality Model, then run the shared contract suite so your provider is held to the same protocol as every other:

func TestChatContract(t *testing.T) {
    modeltest.ChatSuite{
        New:     func(t *testing.T) (chat.Model, chat.Streamer) { return newProvider(t) },
        Request: func(t *testing.T) *chat.Request { return helloRequest() },
    }.Run(t)
}

vectorstore/storetest and history/storetest do the same for backends.

Boundaries

core never imports a sibling module, a provider SDK, a concrete tokenizer vocabulary, or OpenTelemetry. Instrumentation lives in the otel module and decorates Core from the outside. Retries, approvals, planning, and durable execution are Agent or Host concerns.

See ARCHITECTURE.md for the invariants these boundaries rest on.

Documentation

Overview

Package core is the module overview for the Scope narrow waist. It declares no API of its own; every capability lives in a sibling package listed below.

Core owns the serializable, provider-neutral protocols that every provider implements and every capability module consumes: the protocol values, the minimal calling SPI of each modality, and the pure composition around them. It owns no provider SDK, no network backend, no tokenizer vocabulary, no agent control flow, and no telemetry.

Protocol packages

Each modality package owns one request/response protocol and the minimal github.com/Tangerg/scope/core/chat.Model-shaped SPI that carries it:

  • chat: messages, parts, tool calls, usage, and output format.
  • embedding: text-to-vector requests and vectors.
  • image: image generation.
  • moderation: content classification.
  • speech: text-to-speech, with an independent Streamer.
  • transcription: audio-to-text.

Every one of them exports the same three sentinels — ErrInvalidOptions, ErrInvalidRequest, and ErrInvalidResponse — so providers and integrations classify failures identically. Chat extends that triple with its own protocol errors because its wire additionally models tool calls, parts, and usage. Classify with errors.Is; never match on message text.

Shared values

The document, media, and metadata packages own the values the protocols embed: the canonical Document, the Media container shared by every modality, and the JSON-safe typed extension values. A protocol DTO never carries a closure, reader, logger, tracer, registry, or native client.

Cross-protocol capabilities

The jsonschema, tool, tokenizer, history, and vectorstore packages own the capabilities that are not specific to one modality: schema derivation and validation, the executable tool contract with its binding and authorization boundary, token counting and encoding, conversation history, and semantic indexing and search.

Direct clients

The chatclient and embeddingclient packages add the ordinary-path conveniences — immutable defaults, a middleware chain, prompt templates, and structured output — without changing the SPI. The chatclient/safeguard package screens input and output as fail-closed middleware.

Streaming

A modality's Model has only Call. Real streaming is a separate Streamer, so a provider that cannot stream never has to pretend it can. Streams are iter.Seq2 values; early caller stop, context cancellation, and first-error termination are all part of the contract.

Reference implementations and contract suites

The history/inmemory and vectorstore/inmemory packages are zero-dependency reference stores. The modeltest, history/storetest, and vectorstore/storetest packages hold the reusable conformance suites an implementor runs to be held to the same protocol as every other provider. They contain no provider implementation and are never a dependency of production code.

Boundaries

Core never imports a sibling module, a provider SDK, a concrete tokenizer vocabulary, or OpenTelemetry. Instrumentation lives in the otel module and decorates Core from the outside. Retries, approvals, planning, and durable execution are Agent or Host concerns.

See README.md for usage and ARCHITECTURE.md for the invariants these boundaries rest on.

Example

Example shows the ordinary path through the module: build a protocol request, wrap a provider model in a client that owns the defaults, and read the response through the protocol value rather than a provider type.

package main

import (
	"context"
	"fmt"

	"github.com/Tangerg/scope/core/chat"
	"github.com/Tangerg/scope/core/chatclient"
)

// echoModel stands in for a provider so the overview stays runnable. A real
// implementation lives in its own models/<provider> module.
type echoModel struct{}

func (echoModel) Call(_ context.Context, request *chat.Request) (*chat.Response, error) {
	message := chat.NewAssistantMessage(chat.NewTextPart(request.Messages[0].Text()))
	output, err := chat.NewOutput(&message, chat.FinishReasonStop, nil)
	if err != nil {
		return nil, err
	}
	return chat.NewResponse(output, nil)
}

// Example shows the ordinary path through the module: build a protocol request,
// wrap a provider model in a client that owns the defaults, and read the
// response through the protocol value rather than a provider type.
func main() {
	client, err := chatclient.New(echoModel{}, chatclient.Config{
		Defaults: chat.Options{Model: "example-model"},
	})
	if err != nil {
		panic(err)
	}

	request := &chat.Request{
		Messages: []chat.Message{
			chat.NewUserMessage(chat.NewTextPart("hello")),
		},
	}
	response, err := client.Call(context.Background(), request)
	if err != nil {
		panic(err)
	}

	fmt.Println(response.Text())
}
Output:
hello

Directories

Path Synopsis
Package chat defines the serializable provider-neutral chat protocol and its minimal synchronous Model and optional Streamer capabilities.
Package chat defines the serializable provider-neutral chat protocol and its minimal synchronous Model and optional Streamer capabilities.
Package chatclient provides direct, optional conveniences around the minimal chat protocols and model capabilities defined by Core.
Package chatclient provides direct, optional conveniences around the minimal chat protocols and model capabilities defined by Core.
safeguard
Package safeguard provides fail-closed input and output screening as Core chat middleware.
Package safeguard provides fail-closed input and output screening as Core chat middleware.
Package document defines the canonical serializable Document content value shared by extraction, retrieval, and model-facing components.
Package document defines the canonical serializable Document content value shared by extraction, retrieval, and model-facing components.
Package embedding defines the stable text-to-vector protocol and its single-method provider SPI.
Package embedding defines the stable text-to-vector protocol and its single-method provider SPI.
Package embeddingclient provides direct conveniences around Core embedding models for callers that only need vectors.
Package embeddingclient provides direct conveniences around Core embedding models for callers that only need vectors.
Package history defines provider-neutral conversation history contracts and model middleware.
Package history defines provider-neutral conversation history contracts and model middleware.
inmemory
Package inmemory provides a zero-value-ready in-process history store.
Package inmemory provides a zero-value-ready in-process history store.
storetest
Package storetest provides reusable conformance checks for history stores.
Package storetest provides reusable conformance checks for history stores.
Package image defines the serializable image-generation protocol and its single-method Model capability.
Package image defines the serializable image-generation protocol and its single-method Model capability.
internal
ptr
Package ptr holds pointer helpers shared across Core's protocol packages.
Package ptr holds pointer helpers shared across Core's protocol packages.
Package jsonschema derives, parses, and validates JSON Schema contracts.
Package jsonschema derives, parses, and validates JSON Schema contracts.
Package media defines the serializable Media container shared by every modality that accepts non-text payloads.
Package media defines the serializable Media container shared by every modality that accepts non-text payloads.
Package metadata provides JSON-safe extension values for Core protocol types.
Package metadata provides JSON-safe extension values for Core protocol types.
Package modeltest provides reusable contract tests for implementations of Core model interfaces.
Package modeltest provides reusable contract tests for implementations of Core model interfaces.
Package moderation defines the serializable content-moderation protocol and its single-method Model capability.
Package moderation defines the serializable content-moderation protocol and its single-method Model capability.
Package speech defines the stable text-to-speech protocol and independent synchronous Model and optional Streamer provider capabilities.
Package speech defines the stable text-to-speech protocol and independent synchronous Model and optional Streamer provider capabilities.
Package tokenizer defines small, provider-neutral capabilities for counting and encoding text tokens.
Package tokenizer defines small, provider-neutral capabilities for counting and encoding text tokens.
Package tool defines the provider-neutral executable tool contract, its binding and authorization boundaries, typed function adapter, and instance-scoped registry.
Package tool defines the provider-neutral executable tool contract, its binding and authorization boundaries, typed function adapter, and instance-scoped registry.
Package transcription defines the serializable audio-to-text protocol and its single-method Model capability.
Package transcription defines the serializable audio-to-text protocol and its single-method Model capability.
Package vectorstore defines provider-neutral semantic indexing and search.
Package vectorstore defines provider-neutral semantic indexing and search.
filter
Package filter defines the stable metadata-filter expression vocabulary used by vector stores.
Package filter defines the stable metadata-filter expression vocabulary used by vector stores.
inmemory
Package inmemory provides an in-process vector store backed by a map and a configurable similarity function.
Package inmemory provides an in-process vector store backed by a map and a configurable similarity function.
storetest
Package storetest contains provider-independent contract tests for vector-store implementations and their filter visitors.
Package storetest contains provider-independent contract tests for vector-store implementations and their filter visitors.

Jump to

Keyboard shortcuts

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