Build with the local Soterias SDK. Get started with Python and TypeScript.
SoteriasDocsBuild
Core concepts

Models and usage

Keep your model, framework and application code. Soterias runs locally around the calls you choose.

Python
from soterias import ModelUsage, Soterias

sdk = Soterias.local(workflow="personal-assistant")
try:
    def usage(answer):
        reported = answer.usage_metadata or {}
        return ModelUsage(
            "ollama",
            input_tokens=reported.get("input_tokens"),
            output_tokens=reported.get("output_tokens"),
        )

    answer = sdk.invoke_model(chain.invoke, usage, {"question": question})
    result = sdk.invoke(existing_tool, answer.content)
    print(sdk.metrics.snapshot().data())
finally:
    sdk.close()

chain and existing_tool are your existing application objects. For a complete runnable LangChain example, use the Gmail recipe. Gmail code is documentation content; the SDK has no Gmail dependency or mailbox-specific API.

The same pattern in TypeScript:

TypeScript
import {Soterias, type ModelUsage} from '@soterias/core';

const sdk = Soterias.local({workflow: 'personal-assistant'});
try {
  const answer = await sdk.invokeModelAsync(
    (input: typeof inputs) => chain.invoke(input),
    (answer): ModelUsage => ({
      provider: 'ollama',
      inputTokens: answer.usage_metadata?.input_tokens ?? null,
      outputTokens: answer.usage_metadata?.output_tokens ?? null,
    }),
    inputs,
  );
  const result = await sdk.invokeAsync(() => existingTool(answer.content));
  console.log(sdk.metrics.snapshot().data());
} finally {
  await sdk.closeAsync();
}

Use invoke/invokeAsync for ordinary calls. Use invoke_model/invokeModel or their async counterparts when you have provider usage metadata to record. The usage extractor runs after the native application timer stops. Its time and SQLite recording are excluded from the stored application duration. The original return value and exceptions are preserved. Recording failures appear separately in last_recording_error/lastRecordingError.

Missing counts stay unmeasured. A reported zero stays zero. Soterias does not infer model calls, token savings, output quality or cost from a callback. Provider metadata is labelled provider_reported; its digest commits the normalized counts, without authenticating the provider. Prompts, model output, email and credentials are not captured by this helper.

For permission enforcement, execute supported resources through the configured Rust broker with a warrant, current policy and separate human approval. Verify the resulting signed receipts against independently selected trust and expected operation bindings. Wrapping an arbitrary callback observes it; it does not restrict that callback's access. MCP uses the same protected native execution path, with an operator-owned host and separate reviewer.

Available in Python native 0.1.0rc5 (installed by soterias==0.1.4) and TypeScript 0.1.0-rc.5.

Search guides, examples and API reference.