praixis

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 4 Imported by: 0

README

praixis-go

Go SDK for PraixisEngine — a FastAPI backend for local LLM chat sessions and RAG (retrieval-augmented generation) over your own documents.

Zero external dependencies. Stdlib only.


Installation

go get github.com/mettjs/praixis-go

Requires Go 1.22+.


Quick start

import (
    praixis "github.com/mettjs/praixis-go"
    "github.com/mettjs/praixis-go/chat"
    "github.com/mettjs/praixis-go/rag"
)

client := praixis.New("http://localhost:8080", "praixis_your_key")

The client exposes two sub-clients:

Field Package Purpose
client.Chat chat Chat sessions, file summarization, session history
client.RAG rag Vector collections, document Q&A, upload, embed

Chat

Every generative endpoint comes in two flavors: a buffered method that returns the whole result in one call, and a streaming method (suffixed Stream) that yields tokens as they arrive.

Buffered chat
resp, err := client.Chat.Send(ctx, chat.Request{
    Prompt: "Explain Go interfaces in two sentences.",
})
if err != nil { /* handle */ }

fmt.Println(resp.SessionID) // assigned by the server
fmt.Println(resp.Content)   // the full reply

Set ResponseFormat: "json" to ask the model to return JSON; Content is still a string (the model's raw JSON text), which you then unmarshal yourself.

Streaming chat
stream, err := client.Chat.Stream(ctx, chat.Request{
    Prompt: "Explain Go interfaces in two sentences.",
})
if err != nil { /* handle */ }
defer stream.Close()

fmt.Println(stream.SessionID()) // assigned by the server

for stream.Next() {
    fmt.Print(stream.Token())
}
if err := stream.Err(); err != nil { /* handle */ }

Continue an existing session by passing SessionID to either method:

resp, err := client.Chat.Send(ctx, chat.Request{
    Prompt:    "Follow-up question",
    SessionID: previousSessionID,
})
Summarize a file
f, _ := os.Open("report.pdf")
defer f.Close()

// Buffered:
summary, err := client.Chat.SummarizeFile(ctx, "report.pdf", f, nil)
fmt.Println(summary.Filename) // "report.pdf"
fmt.Println(summary.Content)  // the full summary

// Streaming, with options:
stream, err := client.Chat.SummarizeFileStream(ctx, "report.pdf", f,
    &chat.FileSummaryOptions{Task: "Extract action items", Tone: "Bullet points"},
)
defer stream.Close()

fmt.Println(stream.Filename())  // "report.pdf"
fmt.Println(stream.Progress())  // e.g. "reducing 4 chunks"
for stream.Next() {
    fmt.Print(stream.Token())
}
if stream.BackendError() != "" {
    // server-side error (e.g. GPU busy) reported inside the stream
}
Session management
// Fetch message history
history, err := client.Chat.History(ctx, sessionID)
for _, msg := range history.History {
    fmt.Printf("[%s] %s\n", msg.Role, msg.Content)
}

// List all active sessions
sessions, err := client.Chat.ListSessions(ctx)

// Delete a session
err = client.Chat.DeleteSession(ctx, sessionID)

RAG

Ask a question
// Buffered:
resp, err := client.RAG.Ask(ctx, rag.QuestionRequest{
    CollectionName: "hr-docs",
    Question:       "How many vacation days do employees get?",
})
if err != nil { /* handle */ }
fmt.Println(resp.SessionID)   // session for follow-up questions
fmt.Println(resp.SearchQuery) // reformulated query used for retrieval
fmt.Println(resp.Sources)     // []string{"policy.pdf", "hr-handbook.docx"}
fmt.Println(resp.Content)     // the full answer

// Streaming:
stream, err := client.RAG.AskStream(ctx, rag.QuestionRequest{
    CollectionName: "hr-docs",
    Question:       "How many vacation days do employees get?",
})
if err != nil { /* handle */ }
defer stream.Close()

fmt.Println(stream.SessionID())   // session for follow-up questions
fmt.Println(stream.SearchQuery()) // reformulated query used for retrieval

for stream.Next() {
    fmt.Print(stream.Token())
}
if err := stream.Err(); err != nil { /* handle */ }

fmt.Println(stream.Sources()) // []string{"policy.pdf", "hr-handbook.docx"}

Restrict retrieval to a single source document with MetadataFilter. The only honored key is source; any other keys are ignored (not an error):

rag.QuestionRequest{
    CollectionName: "hr-docs",
    Question:       "What is the notice period?",
    MetadataFilter: map[string]any{"source": "policy.pdf"},
}
Upload documents
f, _ := os.Open("policy.pdf")
defer f.Close()

resp, err := client.RAG.Upload(ctx,
    []rag.FileUpload{{Filename: "policy.pdf", Data: f}},
    &rag.UploadOptions{
        CollectionName:   "hr-docs",
        ChunkingStrategy: "semantic", // or "character" for fixed-size splits
        ChunkSize:        praixis.Ptr(2000),
        ChunkOverlap:     praixis.Ptr(150), // only used when ChunkingStrategy is "character"
        ImprovedSearch:   true,             // background hypothetical-question indexing for better natural-language search
    },
)
// resp.Succeeded, resp.Results[i].Status

Pass nil for UploadOptions to use server defaults (collection "main", semantic chunking, chunk size 2000).

Filename is required — it is the document's stored identity and the server's primary format signal, so prefer a .pdf/.docx/.txt extension. For extension-less names the server falls back to the part's Content-Type (filled from the extension when ContentType is empty), then to the file's magic bytes.

ImprovedSearch enables hypothetical-question indexing: questions are generated in the background after the upload returns, so the document is searchable immediately and natural-language matching improves once generation finishes.

Collections
// List all collections
list, err := client.RAG.ListCollections(ctx)
// list.ActiveCollections []string, list.TotalDocuments int

// Files in a collection
files, err := client.RAG.ListFiles(ctx, "hr-docs")

// Delete a file from a collection
err = client.RAG.DeleteFile(ctx, "hr-docs", "old-policy.pdf")

// Delete an entire collection
err = client.RAG.DeleteCollection(ctx, "hr-docs")
Summarize / compare files
// LLM summary of a stored file (buffered)
summary, err := client.RAG.SummarizeDocument(ctx, "hr-docs", "policy.pdf", nil)
fmt.Println(summary.Content)

// Bullet-point diff between two files (buffered)
cmp, err := client.RAG.Compare(ctx, "hr-docs", "policy-v1.pdf", "policy-v2.pdf", nil)
fmt.Println(cmp.Content)

Both take an optional final argument for ResponseFormat ("text" or "json") and have streaming counterparts SummarizeDocumentStream / CompareStream:

stream, err := client.RAG.CompareStream(ctx, "hr-docs", "v1.pdf", "v2.pdf",
    &rag.CompareOptions{ResponseFormat: "json"})
defer stream.Close()
for stream.Next() {
    fmt.Print(stream.Token())
}
Embedding
resp, err := client.RAG.Embed(ctx, "some text to embed")
// resp.Embedding []float64 (384 dimensions), resp.Dimensions int

Error handling

_, err := client.Chat.Stream(ctx, chat.Request{Prompt: "hi"})

switch {
case praixis.IsGPUBusy(err):
    // 503 — server is processing another request; retry after a moment
case praixis.IsRateLimit(err):
    // 429 — slow down
case praixis.IsUnauthorized(err):
    // 401/403 — check your API key
case praixis.IsNotFound(err):
    // 404 — collection, file, or session does not exist
}

The helpers live on the top-level praixis package. For full detail, extract the typed error with errors.As:

var apiErr *praixis.APIError
if errors.As(err, &apiErr) {
    fmt.Println(apiErr.StatusCode, apiErr.Message)
}

Configuration

client := praixis.New(baseURL, apiKey,
    praixis.WithTimeout(60*time.Second), // default 30s; does not affect streams
)

Streams are not subject to the HTTP timeout — cancel them via context.Context:

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
stream, err := client.Chat.Stream(ctx, ...)

Examples

Runnable examples are in _examples/:

Directory Description
_examples/chat_stream Stream a single chat turn
_examples/rag_ask Ask a question over a collection
_examples/rag_upload Upload a file into a collection
PRAIXIS_URL=http://localhost:8080 PRAIXIS_API_KEY=praixis_xxx go run ./_examples/chat_stream

Package layout

praixis-go/
├── praixis.go          # New(), Ptr(), error helpers (APIError, IsGPUBusy, …), Option types
├── chat/
│   ├── types.go        # Request, ChatResponse, FileSummary, History, FileSummaryOptions, …
│   ├── stream.go       # ChatStream, FileSummaryStream
│   └── client.go       # Send, Stream, SummarizeFile, SummarizeFileStream, History, …
├── rag/
│   ├── types.go        # QuestionRequest, AskResponse, FileUpload, UploadOptions, …
│   ├── stream.go       # AskStream, SummaryStream, CompareStream
│   └── client.go       # Ask, AskStream, Upload, Embed, SummarizeDocument, Compare, ListCollections, …
└── internal/
    ├── httpclient.go   # DoJSON, DoStream, DoMultipart, APIError, …
    └── stream.go       # StreamReader (metadata + token iterator)

License

MIT — see LICENSE.

Documentation

Overview

Package praixis is the top-level entry point for the Praixis Go SDK.

Create a client with your server URL and API key, then access the Chat and RAG sub-clients directly:

client := praixis.New("http://localhost:8080", "praixis_your_key")

// streaming chat
stream, err := client.Chat.Stream(ctx, chat.Request{Prompt: "Hello"})

// RAG question
stream, err := client.RAG.Ask(ctx, rag.QuestionRequest{
    CollectionName: "docs",
    Question:       "What is the refund policy?",
})

Index

Constants

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout is the HTTP request timeout applied to non-streaming requests. Streaming endpoints are not subject to this timeout; use context.Context instead.

Variables

This section is empty.

Functions

func IsGPUBusy

func IsGPUBusy(err error) bool

IsGPUBusy reports whether err is a 503 response, meaning the server's GPU slots are exhausted. Retry after a short delay.

func IsNotFound added in v0.3.1

func IsNotFound(err error) bool

IsNotFound reports whether err is a 404 response — a collection, file, or session that does not exist (or belongs to another app).

func IsRateLimit

func IsRateLimit(err error) bool

IsRateLimit reports whether err is a 429 Too Many Requests response.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized reports whether err is a 401 or 403 response, usually meaning the API key is missing or invalid.

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to v. It is a convenience for setting optional pointer fields such as rag.UploadOptions.ChunkSize, since Go does not allow taking the address of a literal (e.g. &800 is invalid).

opts := &rag.UploadOptions{ChunkSize: praixis.Ptr(800)}

Types

type APIError

type APIError = internal.APIError

APIError is returned for any non-2xx HTTP response. It carries the HTTP status code and the server's error message. Use errors.As to extract it, or the IsGPUBusy / IsRateLimit / IsUnauthorized / IsNotFound helpers to test for common cases.

type Client

type Client struct {
	Chat *chat.Client
	RAG  *rag.Client
}

Client is the root Praixis SDK client. Access capabilities through the Chat and RAG fields.

func New

func New(baseURL, apiKey string, opts ...Option) *Client

New creates a Client pointed at baseURL, authenticating with apiKey. baseURL should not have a trailing slash (e.g. "http://localhost:8080").

type Option

type Option func(*options)

Option configures the Client.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout overrides the default HTTP request timeout (30 s). Streaming endpoints ignore this timeout — use context.Context for cancellation on streams.

Directories

Path Synopsis
_examples
chat_stream command
chat_stream demonstrates streaming a single-turn chat request.
chat_stream demonstrates streaming a single-turn chat request.
rag_ask command
rag_ask demonstrates asking a question against a RAG collection.
rag_ask demonstrates asking a question against a RAG collection.
rag_upload command
rag_upload demonstrates uploading a file into a RAG collection.
rag_upload demonstrates uploading a file into a RAG collection.
Package chat provides a client for the Praixis chat and file-summary endpoints.
Package chat provides a client for the Praixis chat and file-summary endpoints.
Package internal provides the low-level HTTP and stream-parsing primitives shared across all SDK resource clients.
Package internal provides the low-level HTTP and stream-parsing primitives shared across all SDK resource clients.
Package rag provides a client for the Praixis RAG (retrieval-augmented generation) and vector-store endpoints.
Package rag provides a client for the Praixis RAG (retrieval-augmented generation) and vector-store endpoints.

Jump to

Keyboard shortcuts

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