# Start with a function, then add your agent

Use Python `soterias==0.1.2` (native `0.1.0rc3`) and TypeScript
`@soterias/core@0.1.0-rc.3` for these programs. The earlier `local` and `invoke`
entry points remain supported; earlier distributions are immutable.

Moving an existing npm project? Follow the
[package migration guide](../../../docs/recipes/package-migration.md) for the
core library, optional integration imports and MCP server names.

This component covers original feature 58, the easy SDK entry point. The folder
number does not establish acceptance of build Task 58. Accepted build tasks stay
22/65; complete recovery, named-client and production gates remain separate.

## One function, no model required

Install the matching updated SDK in your Python environment or Node project.
From this checkout:

```sh
python examples/tasks/58-easy-sdk/start.py
node examples/tasks/58-easy-sdk/start.mjs
```

Both complete programs print a total of `1500`, one recorded call, and the path
to a new private metrics store. They do not delete the store. Python's `with`
closes the client; the Node example closes it in `finally`.

The programs use the real native clock and SQLite storage. No model, daemon,
Docker, API key, policy file or cloud account is required. They observe an
ordinary callback and confer no document or tool permissions. A tiny arithmetic
call demonstrates integration, not a speedup.

## Use your existing LangChain agent

The integration is optional. For Python install the matching SDK's LangChain
extra, plus the example provider:

```sh
python -m pip install "soterias[langchain]" langchain-ollama==1.1.0
```

For Node, install dependencies in the project where the example runs:

```sh
npm install @soterias/core langchain@1.6.6 @langchain/ollama@1.3.0 zod
```

Start your own local Ollama service and make `qwen3.5:4b` available before running
these programs. A model download is an explicit application setup step; Soterias
does not install a model. `OLLAMA_MODEL` and `OLLAMA_BASE_URL` select another
compatible existing model/endpoint.

```sh
python examples/tasks/58-easy-sdk/langchain_agent.py
node examples/tasks/58-easy-sdk/langchain_agent.mjs
```

These complete source files build a real LangChain agent, register one typed
calculation tool, add Soterias middleware and invoke the agent on public synthetic
data. Each asserts that the model actually called the tool with quantity `6`
and unit price `1200`, and that the response contains `7200`. They print the
actual calls and native metrics. Generated language varies; no quality score,
deterministic model behavior or savings is promised. The tool uses an explicitly qualified native calculation after three training,
one held-out and one canary run. Setup time is also recorded. Its report shows
one reused duplicate expression; no model call is skipped. It remains ordinary
trusted application code; use the protected broker examples for permission enforcement.

`SoteriasMiddleware(client)` in Python and `soteriasMiddleware(client)` in
TypeScript wrap each model/tool handler once. They preserve the original
request, result, error and state commands. Native Rust owns clocks, usage
validation, provenance labels and SQLite. The adapter reads explicit LangChain
usage metadata; missing counts stay unknown. It stores no prompts, message
bodies, tool arguments or returned text. The framework and provider retain their
own behavior and configuration.

The middleware does not retry, cache, approve actions, change prompts, select
tools, isolate a process or issue a warrant. Put it inside retry/cache middleware
to measure the handlers that actually execute. A returned handler is not a
verified business outcome. The summary's `unverified` count correctly reflects
that distinction. The examples perform no Gmail/Google calls.

## Learn, authorize and review

Continue with the full [agent integration guide](../../../docs/recipes/agents.md)
and [protected workflows](../../../docs/recipes/protected-workflows.md).
The existing [learning example](../42-48-procedures/learn.py) shows qualified
native procedure memory; the protected Python/TypeScript examples show current
authorization, separate signed approvals and original receipts. A procedure is
not an authority object or an automatic replacement for your LangChain agent.

For async Python applications use `async with Soterias(...)`, `run_async`,
`run_model_async` and `summary_async`. Context cleanup drains accepted recording
jobs; cancelling a wait never proves application effects were rolled back.
Own your application tasks and provider cancellation separately. Synchronous
`with` blocks its calling thread while draining; use `async with` inside an
async application.

Implementation and limits are tested with real native storage and a real local
model. Unit metadata fixtures are separately labeled. Windows/Linux installation
of new versioned archives, docs publication and full production acceptance are
separate release gates. This is an original feature58/59 component, not closure
of those features, Task16 or a new accepted build-task count.
