feat: add Python SDK facade and per-session isolation
This commit is contained in:
@@ -115,6 +115,7 @@
|
||||
- [Configuration](#️-configuration)
|
||||
- [Multiple Instances](#-multiple-instances)
|
||||
- [CLI Reference](#-cli-reference)
|
||||
- [Python SDK](#-python-sdk)
|
||||
- [OpenAI-Compatible API](#-openai-compatible-api)
|
||||
- [Docker](#-docker)
|
||||
- [Linux Service](#-linux-service)
|
||||
@@ -1571,6 +1572,40 @@ The agent can also manage this file itself — ask it to "add a periodic task" a
|
||||
|
||||
</details>
|
||||
|
||||
## 🐍 Python SDK
|
||||
|
||||
Use nanobot as a library — no CLI, no gateway, just Python:
|
||||
|
||||
```python
|
||||
from nanobot import Nanobot
|
||||
|
||||
bot = Nanobot.from_config()
|
||||
result = await bot.run("Summarize the README")
|
||||
print(result.content)
|
||||
```
|
||||
|
||||
Each call carries a `session_key` for conversation isolation — different keys get independent history:
|
||||
|
||||
```python
|
||||
await bot.run("hi", session_key="user-alice")
|
||||
await bot.run("hi", session_key="task-42")
|
||||
```
|
||||
|
||||
Add lifecycle hooks to observe or customize the agent:
|
||||
|
||||
```python
|
||||
from nanobot.agent import AgentHook, AgentHookContext
|
||||
|
||||
class AuditHook(AgentHook):
|
||||
async def before_execute_tools(self, ctx: AgentHookContext) -> None:
|
||||
for tc in ctx.tool_calls:
|
||||
print(f"[tool] {tc.name}")
|
||||
|
||||
result = await bot.run("Hello", hooks=[AuditHook()])
|
||||
```
|
||||
|
||||
See [docs/PYTHON_SDK.md](docs/PYTHON_SDK.md) for the full SDK reference.
|
||||
|
||||
## 🔌 OpenAI-Compatible API
|
||||
|
||||
nanobot can expose a minimal OpenAI-compatible endpoint for local integrations:
|
||||
@@ -1580,11 +1615,11 @@ pip install "nanobot-ai[api]"
|
||||
nanobot serve
|
||||
```
|
||||
|
||||
By default, the API binds to `127.0.0.1:8900`.
|
||||
By default, the API binds to `127.0.0.1:8900`. You can change this in `config.json`.
|
||||
|
||||
### Behavior
|
||||
|
||||
- Fixed session: all requests share the same nanobot session (`api:default`)
|
||||
- Session isolation: pass `"session_id"` in the request body to isolate conversations; omit for a shared default session (`api:default`)
|
||||
- Single-message input: each request must contain exactly one `user` message
|
||||
- Fixed model: omit `model`, or pass the same model shown by `/v1/models`
|
||||
- No streaming: `stream=true` is not supported
|
||||
@@ -1601,12 +1636,8 @@ By default, the API binds to `127.0.0.1:8900`.
|
||||
curl http://127.0.0.1:8900/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "hi"
|
||||
}
|
||||
]
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"session_id": "my-session"
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -1618,9 +1649,8 @@ import requests
|
||||
resp = requests.post(
|
||||
"http://127.0.0.1:8900/v1/chat/completions",
|
||||
json={
|
||||
"messages": [
|
||||
{"role": "user", "content": "hi"}
|
||||
]
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"session_id": "my-session", # optional: isolate conversation
|
||||
},
|
||||
timeout=120,
|
||||
)
|
||||
@@ -1641,6 +1671,7 @@ client = OpenAI(
|
||||
resp = client.chat.completions.create(
|
||||
model="MiniMax-M2.7",
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
extra_body={"session_id": "my-session"}, # optional: isolate conversation
|
||||
)
|
||||
print(resp.choices[0].message.content)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user