Metadata-Version: 2.5
Name: konstera-sdk
Version: 0.6.2
Summary: Python SDK for building Konstera agents. Wraps the MCP callback protocol and the /invoke HTTP contract so agent authors write business logic, not plumbing.
Project-URL: Homepage, https://konstera.example
Project-URL: Documentation, https://konstera.example/docs/sdk-python
Project-URL: Repository, https://github.com/konstera/konstera
Author-email: Konstera <hello@konstera.example>
License: Apache-2.0
Keywords: agents,ai,konstera,llm,mcp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: httpx>=0.28.0
Requires-Dist: mcp>=2.0.0
Requires-Dist: starlette>=0.41.0
Requires-Dist: uvicorn[standard]>=0.30.0
Provides-Extra: dev
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Description-Content-Type: text/markdown

<img src="https://raw.githubusercontent.com/Konstera/sdk/main/assets/brand/konstera-mark-blue.png" alt="Konstera" width="64" />

# konstera-sdk (Python)

Build Konstera agents in Python without hand-writing MCP client boilerplate, HTTP servers, or env-var parsing. Subclass `Agent`, override `handle()`, call `run()`.

**Status**: v0.1.0 (M6). Log + LLM (stub) kernel services only. Vector / state / credentials / cost / tool / agents / human / prompt come in M7.

## Install

The SDK ships as a Python package. During development, install from source:

```bash
pip install -e sdk/python
```

Container agents install it via a multi-stage Dockerfile — the SDK wheel is built in one stage and copied into the final image. See `agents/hello-world-python/Dockerfile` for the reference pattern.

## Minimal agent

```python
from konstera_sdk import Agent, AgentContext, AgentRequest, AgentResponse, run

class HelloAgent(Agent):
    async def handle(self, req: AgentRequest, ctx: AgentContext) -> AgentResponse:
        name = req.input.strip() or "world"
        await ctx.log.info(f"Hello, {name}!", input=name, language="python")
        return AgentResponse(content=f"Hello, {name}!")

if __name__ == "__main__":
    run(HelloAgent())
```

That's it — ~10 lines for a complete agent. `run()` handles:

- Reading `KONSTERA_KERNEL_MCP_URL`, `KONSTERA_AGENT_INSTANCE_ID`, `KONSTERA_AGENT_ID`, `KONSTERA_AGENT_VERSION` from the environment (injected by the kernel's `ContainerAgentHost`)
- Setting up the MCP client back to the kernel
- Hosting `/health`, `/describe`, `/invoke` on port 8080
- Routing invocations to your `handle()`
- Graceful shutdown

## API

### `Agent` (base class)

```python
class Agent:
    async def initialize(self, ctx: AgentContext) -> None: ...
    async def handle(self, req: AgentRequest, ctx: AgentContext) -> AgentResponse: ...
    async def shutdown(self, ctx: AgentContext) -> None: ...
```

Override `handle()` (required). Override `initialize()` / `shutdown()` for setup/teardown.

### `AgentContext`

```python
ctx.instance_id     # str — this agent instance's UUID
ctx.agent_id        # str — e.g. "io.konstera.hello-world-python"
ctx.agent_version   # str — e.g. "0.1.0"
ctx.log             # LogService — ctx.log.info/warn/error
ctx.llm             # LlmService — ctx.llm.complete (stub in M6)
```

### `LogService`

```python
await ctx.log.info(message, **fields)
await ctx.log.warn(message, **fields)
await ctx.log.error(message, **fields)
```

Structured fields (kwargs) are JSON-serialised and enriched by the kernel with tenant/instance/invocation context, then flowed to Serilog + App Insights.

### `LlmService` (stub in M6)

```python
text = await ctx.llm.complete(model="claude-sonnet-4-6", prompt="Hello")
```

Real Claude / OpenAI / Gemini adapters land in M10 (SPEC §10). Interface is stable now; agent code written today will keep working when the stub goes away.

### `run(agent, port=8080)`

Blocks until the process is stopped. Handles all lifecycle: reads env, creates context, calls `initialize()`, serves HTTP, calls `shutdown()` on SIGTERM.

## Direct-run mode

When `KONSTERA_KERNEL_MCP_URL` is unset, kernel callbacks become no-ops (they log a warning and return successfully). This lets you develop agents locally without the full Konstera stack running:

```bash
python -m your_agent_module
# Serves on :8080 — POST /invoke works but ctx.log/ctx.llm skip.
```

## Licence

Apache-2.0. See the repo-level [`LICENSE`](https://github.com/Konstera/sdk/blob/main/LICENSE).
