asgard-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- asgard_sdk-0.1.0/.github/workflows/ci.yml +30 -0
- asgard_sdk-0.1.0/.github/workflows/publish.yml +40 -0
- asgard_sdk-0.1.0/.gitignore +10 -0
- asgard_sdk-0.1.0/.python-version +1 -0
- asgard_sdk-0.1.0/CLAUDE.md +48 -0
- asgard_sdk-0.1.0/PKG-INFO +174 -0
- asgard_sdk-0.1.0/README.md +160 -0
- asgard_sdk-0.1.0/docs/superpowers/plans/2026-05-07-asgard-cli.md +1397 -0
- asgard_sdk-0.1.0/docs/superpowers/plans/2026-05-07-asgard-python-sdk.md +1763 -0
- asgard_sdk-0.1.0/docs/superpowers/specs/2026-05-07-asgard-python-sdk-design.md +312 -0
- asgard_sdk-0.1.0/docs/superpowers/specs/2026-05-07-cli-design.md +156 -0
- asgard_sdk-0.1.0/main.py +6 -0
- asgard_sdk-0.1.0/pyproject.toml +38 -0
- asgard_sdk-0.1.0/src/asgard/__init__.py +37 -0
- asgard_sdk-0.1.0/src/asgard/_http.py +107 -0
- asgard_sdk-0.1.0/src/asgard/bot_provider.py +64 -0
- asgard_sdk-0.1.0/src/asgard/cli.py +376 -0
- asgard_sdk-0.1.0/src/asgard/config.py +7 -0
- asgard_sdk-0.1.0/src/asgard/function_agent.py +53 -0
- asgard_sdk-0.1.0/src/asgard/models/__init__.py +43 -0
- asgard_sdk-0.1.0/src/asgard/models/_base.py +10 -0
- asgard_sdk-0.1.0/src/asgard/models/consent.py +28 -0
- asgard_sdk-0.1.0/src/asgard/models/errors.py +28 -0
- asgard_sdk-0.1.0/src/asgard/models/message.py +46 -0
- asgard_sdk-0.1.0/src/asgard/models/sse_event.py +125 -0
- asgard_sdk-0.1.0/src/asgard/models/template.py +56 -0
- asgard_sdk-0.1.0/src/asgard/streaming.py +33 -0
- asgard_sdk-0.1.0/tests/__init__.py +0 -0
- asgard_sdk-0.1.0/tests/models/__init__.py +0 -0
- asgard_sdk-0.1.0/tests/models/test_consent.py +44 -0
- asgard_sdk-0.1.0/tests/models/test_errors.py +36 -0
- asgard_sdk-0.1.0/tests/models/test_message.py +50 -0
- asgard_sdk-0.1.0/tests/models/test_sse_event.py +115 -0
- asgard_sdk-0.1.0/tests/models/test_template.py +28 -0
- asgard_sdk-0.1.0/tests/test_bot_provider.py +102 -0
- asgard_sdk-0.1.0/tests/test_cli.py +298 -0
- asgard_sdk-0.1.0/tests/test_config.py +13 -0
- asgard_sdk-0.1.0/tests/test_function_agent.py +46 -0
- asgard_sdk-0.1.0/tests/test_http.py +97 -0
- asgard_sdk-0.1.0/tests/test_streaming.py +85 -0
- asgard_sdk-0.1.0/uv.lock +357 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
lint-and-test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v5
|
|
15
|
+
with:
|
|
16
|
+
enable-cache: true
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version-file: .python-version
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv pip install -e ".[dev]" --system
|
|
25
|
+
|
|
26
|
+
- name: Lint (ruff)
|
|
27
|
+
run: ruff check .
|
|
28
|
+
|
|
29
|
+
- name: Test
|
|
30
|
+
run: pytest
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: publish.yml
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
enable-cache: true
|
|
24
|
+
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version-file: .python-version
|
|
29
|
+
|
|
30
|
+
- name: Build package
|
|
31
|
+
run: uv build
|
|
32
|
+
|
|
33
|
+
- name: Publish to PyPI
|
|
34
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
35
|
+
|
|
36
|
+
- name: Create GitHub Release
|
|
37
|
+
uses: softprops/action-gh-release@v2
|
|
38
|
+
with:
|
|
39
|
+
generate_release_notes: true
|
|
40
|
+
files: dist/*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
This project uses `uv` for dependency management and `pytest` for testing.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Install dependencies (dev)
|
|
11
|
+
uv pip install -e ".[dev]"
|
|
12
|
+
|
|
13
|
+
# Run all tests
|
|
14
|
+
uv run pytest
|
|
15
|
+
|
|
16
|
+
# Run a single test file
|
|
17
|
+
uv run pytest tests/test_bot_provider.py
|
|
18
|
+
|
|
19
|
+
# Run a single test
|
|
20
|
+
uv run pytest tests/test_bot_provider.py::test_send_message_returns_reply
|
|
21
|
+
|
|
22
|
+
# Run the CLI
|
|
23
|
+
uv run asgard-cli --help
|
|
24
|
+
|
|
25
|
+
# Build distribution
|
|
26
|
+
uv build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
There is no linter configured. Python version is pinned to 3.14 (see `.python-version`).
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
The SDK exposes two top-level clients, both using a shared `HttpCore` transport layer:
|
|
34
|
+
|
|
35
|
+
- **`BotProviderClient`** ([src/asgard/bot_provider.py](src/asgard/bot_provider.py)) — conversational bot interface. Supports REST (`send_message`) and SSE streaming (`stream`), plus blob uploads.
|
|
36
|
+
- **`FunctionAgentClient`** ([src/asgard/function_agent.py](src/asgard/function_agent.py)) — one-shot function agent. Supports JSON trigger and multipart form trigger.
|
|
37
|
+
|
|
38
|
+
**Transport layer** ([src/asgard/_http.py](src/asgard/_http.py)): `HttpCore` builds URLs as `{host}/ns/{namespace}/bot-provider/{name}/{endpoint}`, injects `X-API-KEY` auth, and raises `AsgardError` on non-2xx responses.
|
|
39
|
+
|
|
40
|
+
**SSE streaming** ([src/asgard/streaming.py](src/asgard/streaming.py)): `BotProviderStream` is a context manager and iterator that parses `data:` lines from the response, yields `GenericBotSseEvent` objects, stops on `RUN_DONE`, and raises `AsgardStreamError` on `RUN_ERROR`.
|
|
41
|
+
|
|
42
|
+
**Models** ([src/asgard/models/](src/asgard/models/)): All Pydantic models extend `CamelModel` (from `_base.py`), which uses `alias_generator=to_camel` so Python snake_case fields serialize/deserialize as camelCase JSON automatically. Call `.model_dump(by_alias=True)` when sending to the API.
|
|
43
|
+
|
|
44
|
+
**SSE event structure**: Every SSE event is a `GenericBotSseEvent` with an `event_type` (`SseEventType` enum) and a `fact` (`GenericBotSseEventFact`). The fact is a union object — only the field matching the event type is populated (e.g., `event.fact.message_delta` for `MESSAGE_DELTA` events).
|
|
45
|
+
|
|
46
|
+
**CLI** ([src/asgard/cli.py](src/asgard/cli.py)): Interactive REPL (`--agent bot`) or one-shot runner (`--agent function`). `BotSession` dataclass tracks channel ID, transport mode, debug flag, and attached blob IDs across REPL turns. All config can come from env vars (`EDGE_SERVER_HOST`, `NAMESPACE`, `BOT_PROVIDER_NAME`, `BOT_PROVIDER_API_KEY`).
|
|
47
|
+
|
|
48
|
+
**Testing**: Tests use `respx` to mock HTTP requests for REST calls, and `httpx.MockTransport` for SSE streaming tests (since `respx` doesn't support streaming). The `http_client` constructor parameter on both clients accepts an injected `httpx.Client` for test isolation.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: asgard-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Asgard Core API
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: httpx>=0.27
|
|
7
|
+
Requires-Dist: pydantic>=2.0
|
|
8
|
+
Provides-Extra: dev
|
|
9
|
+
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
|
|
10
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
11
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
12
|
+
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# asgard-sdk-python
|
|
16
|
+
|
|
17
|
+
Python SDK for the Asgard Core API. Sync-first, with async extensibility in mind.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv add asgard-sdk-python
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or for development:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv sync --extra dev
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
Python 3.11+
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### BotProviderClient
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from asgard import BotProviderClient, GenericBotMessage
|
|
41
|
+
|
|
42
|
+
client = BotProviderClient(
|
|
43
|
+
host="http://localhost:8080",
|
|
44
|
+
namespace="my-ns",
|
|
45
|
+
bot_provider_name="my-bot",
|
|
46
|
+
api_key="secret",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Send a message (REST)
|
|
50
|
+
message = GenericBotMessage(custom_channel_id="ch-1", custom_message_id="m-1", text="hello")
|
|
51
|
+
reply = client.send_message(message)
|
|
52
|
+
for m in reply.messages:
|
|
53
|
+
print(m.text)
|
|
54
|
+
|
|
55
|
+
# Stream a message (SSE)
|
|
56
|
+
with client.stream(message) as stream:
|
|
57
|
+
for event in stream:
|
|
58
|
+
if event.event_type.value == "asgard.message.delta":
|
|
59
|
+
print(event.fact.message_delta.text, end="", flush=True)
|
|
60
|
+
|
|
61
|
+
# Upload a blob
|
|
62
|
+
with open("image.png", "rb") as f:
|
|
63
|
+
blobs = client.upload_blob(custom_channel_id="ch-1", file=f, filename="image.png", mime="image/png")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### FunctionAgentClient
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from asgard import FunctionAgentClient
|
|
70
|
+
|
|
71
|
+
client = FunctionAgentClient(
|
|
72
|
+
host="http://localhost:8080",
|
|
73
|
+
namespace="my-ns",
|
|
74
|
+
bot_provider_name="my-agent",
|
|
75
|
+
api_key="secret",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
result = client.trigger_json({"key": "value"})
|
|
79
|
+
|
|
80
|
+
with open("data.csv", "rb") as f:
|
|
81
|
+
result = client.trigger_form({"key": "value"}, file=f, filename="data.csv", mime="text/csv")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Environment Variables
|
|
85
|
+
|
|
86
|
+
| Variable | Description |
|
|
87
|
+
|----------|-------------|
|
|
88
|
+
| `EDGE_SERVER_HOST` | EdgeServer host URL |
|
|
89
|
+
| `NAMESPACE` | Asgard namespace |
|
|
90
|
+
| `BOT_PROVIDER_NAME` | Bot/agent name |
|
|
91
|
+
| `BOT_PROVIDER_API_KEY` | API key |
|
|
92
|
+
|
|
93
|
+
## CLI
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Bot interactive REPL (SSE by default)
|
|
97
|
+
asgard-cli --host http://localhost:8080 --namespace default --bot my-bot --apikey secret
|
|
98
|
+
|
|
99
|
+
# Switch to REST transport
|
|
100
|
+
asgard-cli --host ... --namespace ... --bot ... --apikey ... --transport rest
|
|
101
|
+
|
|
102
|
+
# Using env vars
|
|
103
|
+
export EDGE_SERVER_HOST=http://localhost:8080
|
|
104
|
+
export NAMESPACE=default
|
|
105
|
+
export BOT_PROVIDER_NAME=my-bot
|
|
106
|
+
export BOT_PROVIDER_API_KEY=secret
|
|
107
|
+
asgard-cli
|
|
108
|
+
|
|
109
|
+
# Function agent — JSON trigger
|
|
110
|
+
asgard-cli --agent function --json-trigger \
|
|
111
|
+
--trigger-payload '{"key": "value"}' \
|
|
112
|
+
--host ... --namespace ... --bot ... --apikey ...
|
|
113
|
+
|
|
114
|
+
# Function agent — Form trigger
|
|
115
|
+
asgard-cli --agent function --form-trigger \
|
|
116
|
+
--trigger-payload '{"key": "value"}' \
|
|
117
|
+
--form-file ./data.csv --form-mime text/csv \
|
|
118
|
+
--host ... --namespace ... --bot ... --apikey ...
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Bot REPL commands
|
|
122
|
+
|
|
123
|
+
| Command | Description |
|
|
124
|
+
|---------|-------------|
|
|
125
|
+
| `/help` | Show help |
|
|
126
|
+
| `/exit` / `/quit` | Exit |
|
|
127
|
+
| `/transport sse\|rest` | Switch transport |
|
|
128
|
+
| `/debug on\|off` | Toggle debug mode |
|
|
129
|
+
| `/blob <path> [mime]` | Upload and attach a blob |
|
|
130
|
+
| `/blobs` | Show attached blob IDs |
|
|
131
|
+
| `/clear-blobs` | Clear attached blobs |
|
|
132
|
+
| `/channel [id]` | Show or switch channel |
|
|
133
|
+
| `/reset [text]` | Send RESET_CHANNEL action |
|
|
134
|
+
|
|
135
|
+
## Error Handling
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from asgard import AsgardError, AsgardStreamError
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
reply = client.send_message(message)
|
|
142
|
+
except AsgardError as e:
|
|
143
|
+
print(e.detail.message) # human-readable error
|
|
144
|
+
print(e.detail.code) # error code
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
with client.stream(message) as stream:
|
|
148
|
+
for event in stream:
|
|
149
|
+
...
|
|
150
|
+
except AsgardStreamError as e:
|
|
151
|
+
print(e.detail.message)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Tool Call Consent
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from asgard import GenericBotMessage, ToolCallConsentResponseItem, ToolCallConsentResult, PostBackAction
|
|
158
|
+
|
|
159
|
+
# After receiving a tool_call.consent event:
|
|
160
|
+
consent_items = [
|
|
161
|
+
ToolCallConsentResponseItem(
|
|
162
|
+
tool_call_id="tc-1",
|
|
163
|
+
result=ToolCallConsentResult.ALLOW_ONCE,
|
|
164
|
+
)
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
response = GenericBotMessage(
|
|
168
|
+
custom_channel_id="ch-1",
|
|
169
|
+
custom_message_id="m-2",
|
|
170
|
+
action=PostBackAction.RESPONSE_TOOL_CALL_CONSENT,
|
|
171
|
+
tool_call_consents=consent_items,
|
|
172
|
+
)
|
|
173
|
+
reply = client.send_message(response)
|
|
174
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# asgard-sdk-python
|
|
2
|
+
|
|
3
|
+
Python SDK for the Asgard Core API. Sync-first, with async extensibility in mind.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv add asgard-sdk-python
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or for development:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv sync --extra dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
Python 3.11+
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### BotProviderClient
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from asgard import BotProviderClient, GenericBotMessage
|
|
27
|
+
|
|
28
|
+
client = BotProviderClient(
|
|
29
|
+
host="http://localhost:8080",
|
|
30
|
+
namespace="my-ns",
|
|
31
|
+
bot_provider_name="my-bot",
|
|
32
|
+
api_key="secret",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Send a message (REST)
|
|
36
|
+
message = GenericBotMessage(custom_channel_id="ch-1", custom_message_id="m-1", text="hello")
|
|
37
|
+
reply = client.send_message(message)
|
|
38
|
+
for m in reply.messages:
|
|
39
|
+
print(m.text)
|
|
40
|
+
|
|
41
|
+
# Stream a message (SSE)
|
|
42
|
+
with client.stream(message) as stream:
|
|
43
|
+
for event in stream:
|
|
44
|
+
if event.event_type.value == "asgard.message.delta":
|
|
45
|
+
print(event.fact.message_delta.text, end="", flush=True)
|
|
46
|
+
|
|
47
|
+
# Upload a blob
|
|
48
|
+
with open("image.png", "rb") as f:
|
|
49
|
+
blobs = client.upload_blob(custom_channel_id="ch-1", file=f, filename="image.png", mime="image/png")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### FunctionAgentClient
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from asgard import FunctionAgentClient
|
|
56
|
+
|
|
57
|
+
client = FunctionAgentClient(
|
|
58
|
+
host="http://localhost:8080",
|
|
59
|
+
namespace="my-ns",
|
|
60
|
+
bot_provider_name="my-agent",
|
|
61
|
+
api_key="secret",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
result = client.trigger_json({"key": "value"})
|
|
65
|
+
|
|
66
|
+
with open("data.csv", "rb") as f:
|
|
67
|
+
result = client.trigger_form({"key": "value"}, file=f, filename="data.csv", mime="text/csv")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Environment Variables
|
|
71
|
+
|
|
72
|
+
| Variable | Description |
|
|
73
|
+
|----------|-------------|
|
|
74
|
+
| `EDGE_SERVER_HOST` | EdgeServer host URL |
|
|
75
|
+
| `NAMESPACE` | Asgard namespace |
|
|
76
|
+
| `BOT_PROVIDER_NAME` | Bot/agent name |
|
|
77
|
+
| `BOT_PROVIDER_API_KEY` | API key |
|
|
78
|
+
|
|
79
|
+
## CLI
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Bot interactive REPL (SSE by default)
|
|
83
|
+
asgard-cli --host http://localhost:8080 --namespace default --bot my-bot --apikey secret
|
|
84
|
+
|
|
85
|
+
# Switch to REST transport
|
|
86
|
+
asgard-cli --host ... --namespace ... --bot ... --apikey ... --transport rest
|
|
87
|
+
|
|
88
|
+
# Using env vars
|
|
89
|
+
export EDGE_SERVER_HOST=http://localhost:8080
|
|
90
|
+
export NAMESPACE=default
|
|
91
|
+
export BOT_PROVIDER_NAME=my-bot
|
|
92
|
+
export BOT_PROVIDER_API_KEY=secret
|
|
93
|
+
asgard-cli
|
|
94
|
+
|
|
95
|
+
# Function agent — JSON trigger
|
|
96
|
+
asgard-cli --agent function --json-trigger \
|
|
97
|
+
--trigger-payload '{"key": "value"}' \
|
|
98
|
+
--host ... --namespace ... --bot ... --apikey ...
|
|
99
|
+
|
|
100
|
+
# Function agent — Form trigger
|
|
101
|
+
asgard-cli --agent function --form-trigger \
|
|
102
|
+
--trigger-payload '{"key": "value"}' \
|
|
103
|
+
--form-file ./data.csv --form-mime text/csv \
|
|
104
|
+
--host ... --namespace ... --bot ... --apikey ...
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Bot REPL commands
|
|
108
|
+
|
|
109
|
+
| Command | Description |
|
|
110
|
+
|---------|-------------|
|
|
111
|
+
| `/help` | Show help |
|
|
112
|
+
| `/exit` / `/quit` | Exit |
|
|
113
|
+
| `/transport sse\|rest` | Switch transport |
|
|
114
|
+
| `/debug on\|off` | Toggle debug mode |
|
|
115
|
+
| `/blob <path> [mime]` | Upload and attach a blob |
|
|
116
|
+
| `/blobs` | Show attached blob IDs |
|
|
117
|
+
| `/clear-blobs` | Clear attached blobs |
|
|
118
|
+
| `/channel [id]` | Show or switch channel |
|
|
119
|
+
| `/reset [text]` | Send RESET_CHANNEL action |
|
|
120
|
+
|
|
121
|
+
## Error Handling
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from asgard import AsgardError, AsgardStreamError
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
reply = client.send_message(message)
|
|
128
|
+
except AsgardError as e:
|
|
129
|
+
print(e.detail.message) # human-readable error
|
|
130
|
+
print(e.detail.code) # error code
|
|
131
|
+
|
|
132
|
+
try:
|
|
133
|
+
with client.stream(message) as stream:
|
|
134
|
+
for event in stream:
|
|
135
|
+
...
|
|
136
|
+
except AsgardStreamError as e:
|
|
137
|
+
print(e.detail.message)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Tool Call Consent
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from asgard import GenericBotMessage, ToolCallConsentResponseItem, ToolCallConsentResult, PostBackAction
|
|
144
|
+
|
|
145
|
+
# After receiving a tool_call.consent event:
|
|
146
|
+
consent_items = [
|
|
147
|
+
ToolCallConsentResponseItem(
|
|
148
|
+
tool_call_id="tc-1",
|
|
149
|
+
result=ToolCallConsentResult.ALLOW_ONCE,
|
|
150
|
+
)
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
response = GenericBotMessage(
|
|
154
|
+
custom_channel_id="ch-1",
|
|
155
|
+
custom_message_id="m-2",
|
|
156
|
+
action=PostBackAction.RESPONSE_TOOL_CALL_CONSENT,
|
|
157
|
+
tool_call_consents=consent_items,
|
|
158
|
+
)
|
|
159
|
+
reply = client.send_message(response)
|
|
160
|
+
```
|