teardrop-cli 0.1.1__tar.gz → 0.3.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.
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/PKG-INFO +80 -8
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/README.md +78 -6
- teardrop_cli-0.3.0/docs/cli-json-schema.md +130 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/docs/cli-reference.md +100 -2
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/pyproject.toml +2 -2
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/_fixtures.py +57 -3
- teardrop_cli-0.3.0/src/teardrop_cli/_templates.py +51 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/cli.py +4 -0
- teardrop_cli-0.3.0/src/teardrop_cli/commands/agent_tools.py +90 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/auth.py +188 -43
- teardrop_cli-0.3.0/src/teardrop_cli/commands/balance.py +201 -0
- teardrop_cli-0.3.0/src/teardrop_cli/commands/chat.py +175 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/config_cmd.py +1 -3
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/earnings.py +33 -19
- teardrop_cli-0.3.0/src/teardrop_cli/commands/event_triggers.py +457 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/llm_config.py +7 -13
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/marketplace.py +57 -27
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/models.py +4 -2
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/quickstart.py +33 -67
- teardrop_cli-0.3.0/src/teardrop_cli/commands/run.py +371 -0
- teardrop_cli-0.3.0/src/teardrop_cli/commands/schedules.py +386 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/tools.py +38 -26
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/config.py +153 -4
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/formatting.py +162 -36
- teardrop_cli-0.3.0/src/teardrop_cli/pricing.py +264 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/conftest.py +129 -1
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/conftest.py +1 -4
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_auth_e2e.py +2 -8
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_billing_e2e.py +13 -3
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_marketplace_e2e.py +3 -9
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_signup_e2e.py +4 -11
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_siwe_login_e2e.py +3 -9
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_auth.py +51 -17
- teardrop_cli-0.3.0/tests/test_billing.py +73 -0
- teardrop_cli-0.3.0/tests/test_chat.py +230 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_credential_priority.py +67 -8
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_earnings.py +2 -6
- teardrop_cli-0.3.0/tests/test_event_triggers.py +240 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_init_and_byok.py +88 -15
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_llm_config.py +3 -9
- teardrop_cli-0.3.0/tests/test_marketplace.py +129 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_models.py +4 -4
- teardrop_cli-0.3.0/tests/test_quickstart.py +218 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_run.py +61 -10
- teardrop_cli-0.3.0/tests/test_schedules.py +217 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_signup.py +5 -15
- teardrop_cli-0.3.0/tests/test_token_expiry_fallback.py +133 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_tools.py +7 -21
- teardrop_cli-0.1.1/docs/cli-json-schema.md +0 -25
- teardrop_cli-0.1.1/src/teardrop_cli/_templates.py +0 -37
- teardrop_cli-0.1.1/src/teardrop_cli/commands/balance.py +0 -74
- teardrop_cli-0.1.1/src/teardrop_cli/commands/run.py +0 -189
- teardrop_cli-0.1.1/tests/test_billing.py +0 -39
- teardrop_cli-0.1.1/tests/test_marketplace.py +0 -80
- teardrop_cli-0.1.1/tests/test_quickstart.py +0 -178
- teardrop_cli-0.1.1/tests/test_token_expiry_fallback.py +0 -62
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.github/workflows/publish.yml +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.github/workflows/test.yml +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.gitignore +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.vscode/settings.json +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/LICENSE +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/__init__.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/_lazy.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/__init__.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/mcp.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/usage.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/README.md +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/__init__.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_run_e2e.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/__init__.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/conftest.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_config_persistence.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_keyring_integration.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_perf_lazygroup.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_siwe_signing.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_config_cmd.py +0 -0
- {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_mcp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: teardrop-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Command-line interface for the Teardrop AI agent platform
|
|
5
5
|
Project-URL: Homepage, https://github.com/teardrop-ai/teardrop-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/teardrop-ai/teardrop-cli
|
|
@@ -45,7 +45,7 @@ Requires-Dist: httpx>=0.27
|
|
|
45
45
|
Requires-Dist: keyring>=25.0
|
|
46
46
|
Requires-Dist: platformdirs>=4.0
|
|
47
47
|
Requires-Dist: rich>=13.0
|
|
48
|
-
Requires-Dist: teardrop-sdk>=0.
|
|
48
|
+
Requires-Dist: teardrop-sdk>=0.2.0
|
|
49
49
|
Requires-Dist: tomli-w>=1.0
|
|
50
50
|
Requires-Dist: typer>=0.12
|
|
51
51
|
Provides-Extra: dev
|
|
@@ -118,14 +118,19 @@ teardrop run "Summarize the latest ETH gas trends"
|
|
|
118
118
|
| Goal | Command |
|
|
119
119
|
|------|---------|
|
|
120
120
|
| Create account & org | `teardrop auth signup` |
|
|
121
|
-
|
|
|
122
|
-
|
|
|
121
|
+
| Generate a new wallet & sign in | `teardrop auth login --siwe --generate-wallet [--save-key]` |
|
|
122
|
+
| Sign in with wallet (existing key) | `teardrop auth login --siwe --key-file wallet.key [--save-key]` |
|
|
123
123
|
| Email + password | `teardrop auth login --email you@example.com` |
|
|
124
124
|
| Pre-issued JWT | `teardrop auth login --token <jwt>` |
|
|
125
|
+
| Invite a team member | `teardrop auth invite colleague@example.com` |
|
|
125
126
|
| Show identity | `teardrop auth status` |
|
|
126
127
|
| Sign out | `teardrop auth logout` |
|
|
127
128
|
|
|
128
|
-
Private keys are never persisted by the CLI
|
|
129
|
+
Private keys are never persisted by the CLI unless you pass ``--save-key``.
|
|
130
|
+
When saved, the key is stored in your OS keyring (never in a config file)
|
|
131
|
+
and can be used for automatic re-authentication when the session token
|
|
132
|
+
expires. An encrypted keyring backend is required — plaintext fallbacks
|
|
133
|
+
are refused.
|
|
129
134
|
|
|
130
135
|
For machine-to-machine credentials, env-var precedence, and CI patterns, see [docs/cli-reference.md](docs/cli-reference.md#authentication).
|
|
131
136
|
|
|
@@ -181,6 +186,15 @@ teardrop run "Follow up" --thread <thread-id>
|
|
|
181
186
|
# Pass structured context
|
|
182
187
|
teardrop run "Process this order" --context '{"order_id":"ord_123"}'
|
|
183
188
|
|
|
189
|
+
# Exclude specific tools
|
|
190
|
+
teardrop run "Summarize news" --exclude platform/web_search
|
|
191
|
+
|
|
192
|
+
# Estimate cost based on current pricing & config (no run performed)
|
|
193
|
+
teardrop run "Analyze this data" --estimate-cost
|
|
194
|
+
|
|
195
|
+
# Apply a tool policy from a file
|
|
196
|
+
teardrop run "Execute workflow" --policy-file policy.json
|
|
197
|
+
|
|
184
198
|
# Machine-readable output
|
|
185
199
|
teardrop run "..." --json --no-stream
|
|
186
200
|
|
|
@@ -188,18 +202,76 @@ teardrop run "..." --json --no-stream
|
|
|
188
202
|
teardrop run "..." --json --with-ui
|
|
189
203
|
```
|
|
190
204
|
|
|
191
|
-
Streaming output renders Markdown live with inline tool calls. A token + cost summary prints at the end. By default, CLI output is optimized for scripting and automation (`emit_ui=false`); use `--with-ui` only if you need structured UI component data in the JSON output.
|
|
205
|
+
Streaming output renders Markdown live with inline tool calls and structured UI components. A token + cost summary prints at the end. By default, CLI output is optimized for scripting and automation (`emit_ui=false`); use `--with-ui` only if you need structured UI component data in the JSON output.
|
|
206
|
+
|
|
207
|
+
---
|
|
192
208
|
|
|
193
|
-
|
|
209
|
+
## Automate Runs
|
|
210
|
+
|
|
211
|
+
Use interval schedules for recurring prompts and event triggers for inbound webhooks:
|
|
194
212
|
|
|
195
213
|
```bash
|
|
196
|
-
teardrop
|
|
214
|
+
teardrop schedules create \
|
|
215
|
+
--name hourly-briefing \
|
|
216
|
+
--prompt "Summarize open incidents" \
|
|
217
|
+
--interval-seconds 3600
|
|
218
|
+
|
|
219
|
+
teardrop schedules list
|
|
220
|
+
teardrop schedules runs <schedule-id>
|
|
221
|
+
|
|
222
|
+
teardrop event-triggers create \
|
|
223
|
+
--name inbound-orders \
|
|
224
|
+
--prompt "Validate and process this order payload"
|
|
225
|
+
|
|
226
|
+
teardrop event-triggers runs <trigger-id>
|
|
227
|
+
teardrop event-triggers rotate-secret <trigger-id>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`event-triggers create` and `event-triggers rotate-secret` print the signing secret once. Store it immediately.
|
|
231
|
+
|
|
232
|
+
Full reference: [docs/cli-reference.md](docs/cli-reference.md#schedules) and [docs/cli-reference.md](docs/cli-reference.md#event-triggers).
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Chat with an Agent
|
|
237
|
+
|
|
238
|
+
A stateful chat mode that automatically continues the same thread across invocations:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
teardrop chat "What is the current ETH gas price?" # auto-creates a thread
|
|
242
|
+
teardrop chat "Follow up on that" # continues the same thread
|
|
243
|
+
teardrop chat "Start fresh" --new # starts a new conversation
|
|
244
|
+
teardrop chat "Specific thread" --thread thr_abc123 # explicit thread by id
|
|
245
|
+
teardrop chat "..." --json # machine-readable output
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The active thread id is stored in `~/.teardrop/config.toml` and reused on your next `teardrop chat` call. The thread id is printed after every turn for copy/paste. All run flags (`--context`, `--exclude`, `--policy-file`, `--estimate-cost`, `--with-ui`, `--no-stream`) are supported.
|
|
249
|
+
|
|
250
|
+
Use `teardrop run` for one-shot, script-friendly calls — use `teardrop chat` for conversational interaction.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
If a run fails on credit, check your balance and history:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
teardrop balance # current credits
|
|
258
|
+
teardrop balance credit-history # past charges and top-ups
|
|
197
259
|
```
|
|
198
260
|
|
|
199
261
|
To add credits, visit [teardrop.dev](https://teardrop.dev).
|
|
200
262
|
|
|
201
263
|
---
|
|
202
264
|
|
|
265
|
+
## Agent Tools
|
|
266
|
+
|
|
267
|
+
List all tools visible to your agent (platform, marketplace subscriptions, and your own tools):
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
teardrop agent-tools list
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
203
275
|
## Configure Your LLM
|
|
204
276
|
|
|
205
277
|
One-shot bring-your-own-key wizard:
|
|
@@ -58,14 +58,19 @@ teardrop run "Summarize the latest ETH gas trends"
|
|
|
58
58
|
| Goal | Command |
|
|
59
59
|
|------|---------|
|
|
60
60
|
| Create account & org | `teardrop auth signup` |
|
|
61
|
-
|
|
|
62
|
-
|
|
|
61
|
+
| Generate a new wallet & sign in | `teardrop auth login --siwe --generate-wallet [--save-key]` |
|
|
62
|
+
| Sign in with wallet (existing key) | `teardrop auth login --siwe --key-file wallet.key [--save-key]` |
|
|
63
63
|
| Email + password | `teardrop auth login --email you@example.com` |
|
|
64
64
|
| Pre-issued JWT | `teardrop auth login --token <jwt>` |
|
|
65
|
+
| Invite a team member | `teardrop auth invite colleague@example.com` |
|
|
65
66
|
| Show identity | `teardrop auth status` |
|
|
66
67
|
| Sign out | `teardrop auth logout` |
|
|
67
68
|
|
|
68
|
-
Private keys are never persisted by the CLI
|
|
69
|
+
Private keys are never persisted by the CLI unless you pass ``--save-key``.
|
|
70
|
+
When saved, the key is stored in your OS keyring (never in a config file)
|
|
71
|
+
and can be used for automatic re-authentication when the session token
|
|
72
|
+
expires. An encrypted keyring backend is required — plaintext fallbacks
|
|
73
|
+
are refused.
|
|
69
74
|
|
|
70
75
|
For machine-to-machine credentials, env-var precedence, and CI patterns, see [docs/cli-reference.md](docs/cli-reference.md#authentication).
|
|
71
76
|
|
|
@@ -121,6 +126,15 @@ teardrop run "Follow up" --thread <thread-id>
|
|
|
121
126
|
# Pass structured context
|
|
122
127
|
teardrop run "Process this order" --context '{"order_id":"ord_123"}'
|
|
123
128
|
|
|
129
|
+
# Exclude specific tools
|
|
130
|
+
teardrop run "Summarize news" --exclude platform/web_search
|
|
131
|
+
|
|
132
|
+
# Estimate cost based on current pricing & config (no run performed)
|
|
133
|
+
teardrop run "Analyze this data" --estimate-cost
|
|
134
|
+
|
|
135
|
+
# Apply a tool policy from a file
|
|
136
|
+
teardrop run "Execute workflow" --policy-file policy.json
|
|
137
|
+
|
|
124
138
|
# Machine-readable output
|
|
125
139
|
teardrop run "..." --json --no-stream
|
|
126
140
|
|
|
@@ -128,18 +142,76 @@ teardrop run "..." --json --no-stream
|
|
|
128
142
|
teardrop run "..." --json --with-ui
|
|
129
143
|
```
|
|
130
144
|
|
|
131
|
-
Streaming output renders Markdown live with inline tool calls. A token + cost summary prints at the end. By default, CLI output is optimized for scripting and automation (`emit_ui=false`); use `--with-ui` only if you need structured UI component data in the JSON output.
|
|
145
|
+
Streaming output renders Markdown live with inline tool calls and structured UI components. A token + cost summary prints at the end. By default, CLI output is optimized for scripting and automation (`emit_ui=false`); use `--with-ui` only if you need structured UI component data in the JSON output.
|
|
146
|
+
|
|
147
|
+
---
|
|
132
148
|
|
|
133
|
-
|
|
149
|
+
## Automate Runs
|
|
150
|
+
|
|
151
|
+
Use interval schedules for recurring prompts and event triggers for inbound webhooks:
|
|
134
152
|
|
|
135
153
|
```bash
|
|
136
|
-
teardrop
|
|
154
|
+
teardrop schedules create \
|
|
155
|
+
--name hourly-briefing \
|
|
156
|
+
--prompt "Summarize open incidents" \
|
|
157
|
+
--interval-seconds 3600
|
|
158
|
+
|
|
159
|
+
teardrop schedules list
|
|
160
|
+
teardrop schedules runs <schedule-id>
|
|
161
|
+
|
|
162
|
+
teardrop event-triggers create \
|
|
163
|
+
--name inbound-orders \
|
|
164
|
+
--prompt "Validate and process this order payload"
|
|
165
|
+
|
|
166
|
+
teardrop event-triggers runs <trigger-id>
|
|
167
|
+
teardrop event-triggers rotate-secret <trigger-id>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`event-triggers create` and `event-triggers rotate-secret` print the signing secret once. Store it immediately.
|
|
171
|
+
|
|
172
|
+
Full reference: [docs/cli-reference.md](docs/cli-reference.md#schedules) and [docs/cli-reference.md](docs/cli-reference.md#event-triggers).
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Chat with an Agent
|
|
177
|
+
|
|
178
|
+
A stateful chat mode that automatically continues the same thread across invocations:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
teardrop chat "What is the current ETH gas price?" # auto-creates a thread
|
|
182
|
+
teardrop chat "Follow up on that" # continues the same thread
|
|
183
|
+
teardrop chat "Start fresh" --new # starts a new conversation
|
|
184
|
+
teardrop chat "Specific thread" --thread thr_abc123 # explicit thread by id
|
|
185
|
+
teardrop chat "..." --json # machine-readable output
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The active thread id is stored in `~/.teardrop/config.toml` and reused on your next `teardrop chat` call. The thread id is printed after every turn for copy/paste. All run flags (`--context`, `--exclude`, `--policy-file`, `--estimate-cost`, `--with-ui`, `--no-stream`) are supported.
|
|
189
|
+
|
|
190
|
+
Use `teardrop run` for one-shot, script-friendly calls — use `teardrop chat` for conversational interaction.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
If a run fails on credit, check your balance and history:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
teardrop balance # current credits
|
|
198
|
+
teardrop balance credit-history # past charges and top-ups
|
|
137
199
|
```
|
|
138
200
|
|
|
139
201
|
To add credits, visit [teardrop.dev](https://teardrop.dev).
|
|
140
202
|
|
|
141
203
|
---
|
|
142
204
|
|
|
205
|
+
## Agent Tools
|
|
206
|
+
|
|
207
|
+
List all tools visible to your agent (platform, marketplace subscriptions, and your own tools):
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
teardrop agent-tools list
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
143
215
|
## Configure Your LLM
|
|
144
216
|
|
|
145
217
|
One-shot bring-your-own-key wizard:
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Teardrop CLI Agent Run JSON Schema
|
|
2
|
+
|
|
3
|
+
When running `teardrop run "..." --json` or `teardrop chat "..." --json`,
|
|
4
|
+
the output is a single JSON object (implies `--no-stream`).
|
|
5
|
+
|
|
6
|
+
## Schema Details
|
|
7
|
+
|
|
8
|
+
The JSON object contains the following fields:
|
|
9
|
+
|
|
10
|
+
- `text` (string): The final text response from the agent.
|
|
11
|
+
- `thread_id` (string | null): The ID of the thread used for the run. This can be used with the `--thread` flag in future runs (or `teardrop chat`) to continue the conversation.
|
|
12
|
+
|
|
13
|
+
## Example Output
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"text": "The price of ETH is currently $2,450.32.",
|
|
18
|
+
"thread_id": "thr_abc123"
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
To capture specific fields, use `jq`:
|
|
24
|
+
```bash
|
|
25
|
+
teardrop run "ETH price" --json | jq -r .text
|
|
26
|
+
teardrop chat "ETH price" --json | jq -r .thread_id
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Schedules (`schedules create/get/list/update --json`)
|
|
32
|
+
|
|
33
|
+
`schedules list --json` returns a JSON array; all other commands return a single object.
|
|
34
|
+
|
|
35
|
+
| Field | Type | Description |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `id` | string (UUID) | Schedule identifier |
|
|
38
|
+
| `org_id` | string | Owning org |
|
|
39
|
+
| `user_id` | string | Creator user |
|
|
40
|
+
| `name` | string | Display name |
|
|
41
|
+
| `prompt` | string | Agent prompt |
|
|
42
|
+
| `schedule_kind` | `"interval"` | Fixed constant |
|
|
43
|
+
| `interval_seconds` | integer | Run frequency |
|
|
44
|
+
| `enabled` | boolean | Active state |
|
|
45
|
+
| `callback_url` | string \| null | Webhook called after each run |
|
|
46
|
+
| `next_run_at` | string (ISO 8601) | Next scheduled time |
|
|
47
|
+
| `last_run_at` | string \| null (ISO 8601) | Last completed run |
|
|
48
|
+
| `consecutive_failures` | integer | Failures since last success |
|
|
49
|
+
| `created_at` | string (ISO 8601) | |
|
|
50
|
+
| `updated_at` | string (ISO 8601) | |
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
teardrop schedules create --name my-schedule --prompt "..." --interval-seconds 3600 --json | jq -r .id
|
|
54
|
+
teardrop schedules update <id> --enabled false --json | jq .enabled
|
|
55
|
+
teardrop schedules list --json | jq '.[].name'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Event Triggers (`event-triggers create/get/list/update --json`)
|
|
61
|
+
|
|
62
|
+
`event-triggers list --json` returns a JSON array; all other commands return a single object.
|
|
63
|
+
|
|
64
|
+
| Field | Type | Description |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `id` | string (UUID) | Trigger identifier |
|
|
67
|
+
| `org_id` | string | Owning org |
|
|
68
|
+
| `user_id` | string | Creator user |
|
|
69
|
+
| `name` | string | Display name |
|
|
70
|
+
| `prompt` | string | Prompt template (supports `{{field}}` / `{{event_json}}`) |
|
|
71
|
+
| `schedule_kind` | `"event"` | Fixed constant |
|
|
72
|
+
| `enabled` | boolean | Active state |
|
|
73
|
+
| `callback_url` | string \| null | Webhook called after each run |
|
|
74
|
+
| `trigger_token` | string | Public route discriminator |
|
|
75
|
+
| `event_path` | string | Inbound dispatch path (e.g. `/agent/events/{trigger_token}`) |
|
|
76
|
+
| `consecutive_failures` | integer | Failures since last success |
|
|
77
|
+
| `last_run_at` | string \| null (ISO 8601) | |
|
|
78
|
+
| `created_at` | string (ISO 8601) | |
|
|
79
|
+
| `updated_at` | string (ISO 8601) | |
|
|
80
|
+
|
|
81
|
+
**`event-triggers create --json` only** additionally includes:
|
|
82
|
+
|
|
83
|
+
| Field | Type | Description |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `secret` | string | Plaintext signing secret — shown once, never retrievable again |
|
|
86
|
+
|
|
87
|
+
**`event-triggers rotate-secret --json`** returns the rotation model (not the full trigger object):
|
|
88
|
+
|
|
89
|
+
| Field | Type | Description |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `id` | string (UUID) | Trigger identifier |
|
|
92
|
+
| `secret` | string | New plaintext signing secret — shown once |
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Capture id and secret on creation for use in CI
|
|
96
|
+
eval $(teardrop event-triggers create --name ci-hook --prompt "..." --json \
|
|
97
|
+
| jq -r '"TRIGGER_ID=" + .id, "TRIGGER_SECRET=" + .secret')
|
|
98
|
+
|
|
99
|
+
teardrop event-triggers list --json | jq '.[].trigger_token'
|
|
100
|
+
teardrop event-triggers rotate-secret <id> --json | jq -r .secret
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Run History (`schedules runs / event-triggers runs --json`)
|
|
106
|
+
|
|
107
|
+
Both commands return the same paginated envelope:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{ "items": [ <ScheduledRunResult>, ... ], "next_cursor": "<cursor> | null" }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Each `ScheduledRunResult` item:
|
|
114
|
+
|
|
115
|
+
| Field | Type | Description |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `id` | string (UUID) | Outcome record ID |
|
|
118
|
+
| `schedule_id` | string (UUID) | Owning schedule or trigger ID |
|
|
119
|
+
| `org_id` | string | |
|
|
120
|
+
| `run_id` | string (UUID) | Core execution thread ID |
|
|
121
|
+
| `status` | `"completed" \| "failed" \| "timeout" \| "skipped"` | |
|
|
122
|
+
| `output_text` | string | Synthesized agent output |
|
|
123
|
+
| `cost_usdc` | integer | Atomic USDC charged ($1.00 = `1000000`) |
|
|
124
|
+
| `error` | string | Sanitized reason on failure; empty on success |
|
|
125
|
+
| `created_at` | string (ISO 8601) | |
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
teardrop schedules runs <id> --json | jq '.items[] | select(.status == "failed") | .error'
|
|
129
|
+
teardrop event-triggers runs <id> --limit 50 --json | jq '.next_cursor'
|
|
130
|
+
```
|
|
@@ -8,6 +8,9 @@ This document covers every flag, env var, and subcommand. For the quick path, st
|
|
|
8
8
|
|
|
9
9
|
- [Authentication](#authentication)
|
|
10
10
|
- [Running Agents](#running-agents)
|
|
11
|
+
- [Chat Sessions](#chat-sessions)
|
|
12
|
+
- [Schedules](#schedules)
|
|
13
|
+
- [Event Triggers](#event-triggers)
|
|
11
14
|
- [Billing & Credits](#billing--credits)
|
|
12
15
|
- [Tool Management](#tool-management)
|
|
13
16
|
- [Marketplace](#marketplace)
|
|
@@ -90,6 +93,88 @@ Streaming output renders Markdown live with inline tool calls. A token + cost su
|
|
|
90
93
|
|
|
91
94
|
---
|
|
92
95
|
|
|
96
|
+
## Chat Sessions
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
teardrop chat "What is the current ETH gas price?" # auto-creates a thread
|
|
100
|
+
teardrop chat "Follow up on that" # continues the same thread
|
|
101
|
+
teardrop chat "Start fresh" --new # starts a new conversation
|
|
102
|
+
teardrop chat "Specific thread" --thread thr_abc123 # explicit thread by id
|
|
103
|
+
teardrop chat "..." --json # machine-readable output
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The active thread id is stored in `~/.teardrop/config.toml` (`chat.active_thread_id`).
|
|
107
|
+
The file is chmod'd 600 and the thread id is printed to stderr after every turn.
|
|
108
|
+
|
|
109
|
+
**Flag precedence** (highest first):
|
|
110
|
+
1. `--new` — clears the stored thread; a fresh one is created server-side.
|
|
111
|
+
2. `--thread <id>` — overrides any stored thread.
|
|
112
|
+
3. **Stored thread** — read from config if neither `--new` nor `--thread` is given.
|
|
113
|
+
4. **Server‑minted** — if none of the above resolve to a value, the server assigns one and it is persisted automatically.
|
|
114
|
+
|
|
115
|
+
Chat supports all the same options as `run` (`--context`, `--exclude`, `--policy-file`,
|
|
116
|
+
`--estimate-cost`, `--with-ui`, `--no-stream`, `--base-url`).
|
|
117
|
+
|
|
118
|
+
**Logout clears state**: `teardrop auth logout` removes both credentials **and**
|
|
119
|
+
the active thread id from the config file. The next `teardrop chat` after logout
|
|
120
|
+
will start a fresh thread.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Schedules
|
|
125
|
+
|
|
126
|
+
Recurring interval-based runs:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
teardrop schedules create \
|
|
130
|
+
--name hourly-briefing \
|
|
131
|
+
--prompt "Summarize open incidents" \
|
|
132
|
+
--interval-seconds 3600
|
|
133
|
+
|
|
134
|
+
teardrop schedules list
|
|
135
|
+
teardrop schedules get <schedule-id>
|
|
136
|
+
teardrop schedules update <schedule-id> --enabled false
|
|
137
|
+
teardrop schedules update <schedule-id> --clear-callback-url
|
|
138
|
+
teardrop schedules runs <schedule-id> --limit 50 --json
|
|
139
|
+
teardrop schedules delete <schedule-id>
|
|
140
|
+
teardrop schedules delete <schedule-id> --yes
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Non-JSON list output includes: `ID`, `Name`, `Enabled`, `Interval`, `Consecutive Failures`, `Last Run At`.
|
|
144
|
+
|
|
145
|
+
Run history output includes: `Run ID`, `Status`, `Cost (USDC)`, `Error Message`, `Executed At`.
|
|
146
|
+
|
|
147
|
+
`--clear-callback-url` sends an explicit `null` callback URL while still preserving PATCH semantics for all other omitted fields.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Event Triggers
|
|
152
|
+
|
|
153
|
+
Reactive runs exposed as signed public webhook endpoints:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
teardrop event-triggers create \
|
|
157
|
+
--name inbound-orders \
|
|
158
|
+
--prompt "Validate and process this order payload"
|
|
159
|
+
|
|
160
|
+
teardrop event-triggers list
|
|
161
|
+
teardrop event-triggers get <trigger-id>
|
|
162
|
+
teardrop event-triggers update <trigger-id> --enabled false
|
|
163
|
+
teardrop event-triggers update <trigger-id> --callback-url https://example.com/hook
|
|
164
|
+
teardrop event-triggers runs <trigger-id> --limit 50 --json
|
|
165
|
+
teardrop event-triggers rotate-secret <trigger-id>
|
|
166
|
+
teardrop event-triggers delete <trigger-id>
|
|
167
|
+
teardrop event-triggers delete <trigger-id> --yes
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`create` and `rotate-secret` display the signing secret once. Store it immediately; subsequent `list` and `get` calls do not return the plaintext secret.
|
|
171
|
+
|
|
172
|
+
Non-JSON list output includes: `ID`, `Name`, `Enabled`, `Kind`, `Consecutive Failures`, `Last Run At`.
|
|
173
|
+
|
|
174
|
+
Run history output includes: `Run ID`, `Status`, `Cost (USDC)`, `Error Message`, `Executed At`.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
93
178
|
## Billing & Credits
|
|
94
179
|
|
|
95
180
|
```bash
|
|
@@ -134,17 +219,30 @@ Example `tool.json`:
|
|
|
134
219
|
{
|
|
135
220
|
"name": "get_weather",
|
|
136
221
|
"description": "Fetch current weather conditions for a given city.",
|
|
137
|
-
"webhook_url": "https://api.example.com/webhooks/teardrop",
|
|
138
222
|
"input_schema": {
|
|
139
223
|
"type": "object",
|
|
140
224
|
"properties": {
|
|
141
225
|
"city": { "type": "string", "description": "City name, e.g. 'London'" }
|
|
142
226
|
},
|
|
143
|
-
"required": ["city"]
|
|
227
|
+
"required": ["city"],
|
|
228
|
+
"additionalProperties": false
|
|
144
229
|
},
|
|
230
|
+
"output_schema": {
|
|
231
|
+
"type": "object",
|
|
232
|
+
"properties": {
|
|
233
|
+
"result": { "type": "string", "description": "Weather summary for the requested city." }
|
|
234
|
+
},
|
|
235
|
+
"required": ["result"],
|
|
236
|
+
"additionalProperties": true
|
|
237
|
+
},
|
|
238
|
+
"webhook_url": "https://api.example.com/webhooks/teardrop",
|
|
239
|
+
"webhook_method": "GET",
|
|
240
|
+
"auth_header_name": null,
|
|
241
|
+
"auth_header_value": null,
|
|
145
242
|
"timeout_seconds": 10,
|
|
146
243
|
"publish_as_mcp": true,
|
|
147
244
|
"marketplace_description": "Real-time weather data for any city worldwide.",
|
|
245
|
+
"category": "data",
|
|
148
246
|
"base_price_usdc": 5000
|
|
149
247
|
}
|
|
150
248
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "teardrop-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Command-line interface for the Teardrop AI agent platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"teardrop-sdk>=0.
|
|
27
|
+
"teardrop-sdk>=0.2.0",
|
|
28
28
|
"typer>=0.12",
|
|
29
29
|
"rich>=13.0",
|
|
30
30
|
"platformdirs>=4.0",
|
|
@@ -176,9 +176,9 @@ def make_benchmarks_response(models: list[dict] | None = None) -> MagicMock:
|
|
|
176
176
|
"supports_streaming": True,
|
|
177
177
|
"quality_tier": 2,
|
|
178
178
|
"pricing": {
|
|
179
|
-
"tokens_in_cost_per_1k": 0
|
|
180
|
-
"tokens_out_cost_per_1k": 0
|
|
181
|
-
"tool_call_cost":
|
|
179
|
+
"tokens_in_cost_per_1k": 1_250.0,
|
|
180
|
+
"tokens_out_cost_per_1k": 6_250.0,
|
|
181
|
+
"tool_call_cost": 1_000.0,
|
|
182
182
|
},
|
|
183
183
|
"benchmarks": {
|
|
184
184
|
"total_runs_7d": 1250,
|
|
@@ -195,3 +195,57 @@ def make_benchmarks_response(models: list[dict] | None = None) -> MagicMock:
|
|
|
195
195
|
obj.models = models
|
|
196
196
|
obj.updated_at = data["updated_at"]
|
|
197
197
|
return obj
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def make_pricing_response(
|
|
201
|
+
base_cost_usdc: int = 500,
|
|
202
|
+
tools: list[dict] | None = None,
|
|
203
|
+
) -> MagicMock:
|
|
204
|
+
"""Return a minimal BillingPricingResponse-like mock."""
|
|
205
|
+
if tools is None:
|
|
206
|
+
tools = [
|
|
207
|
+
{
|
|
208
|
+
"tool_name": "acme/weather",
|
|
209
|
+
"price_usdc": 5000,
|
|
210
|
+
"description": "Get the weather",
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
data = {"tools": tools, "base_cost_usdc": base_cost_usdc, "updated_at": "2026-04-16T12:00:00Z"}
|
|
214
|
+
obj = MagicMock()
|
|
215
|
+
obj.model_dump = lambda: dict(data)
|
|
216
|
+
obj.tools = tools
|
|
217
|
+
obj.base_cost_usdc = base_cost_usdc
|
|
218
|
+
obj.updated_at = data["updated_at"]
|
|
219
|
+
return obj
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def make_credit_history_entries(
|
|
223
|
+
count: int = 3,
|
|
224
|
+
) -> list[MagicMock]:
|
|
225
|
+
"""Return a list of CreditHistoryEntry-like mocks.
|
|
226
|
+
|
|
227
|
+
Each mock has a ``model_dump`` method so the CLI can normalise it, matching
|
|
228
|
+
the real SDK's ``list[CreditHistoryEntry]`` return type.
|
|
229
|
+
"""
|
|
230
|
+
entries = []
|
|
231
|
+
samples = [
|
|
232
|
+
{"reason": "Subscription fee — acme/weather", "amount_usdc": 5000, "operation": "debit"},
|
|
233
|
+
{"reason": "Top-up", "amount_usdc": 50_000_000, "operation": "topup"},
|
|
234
|
+
{"reason": "Agent run — code review", "amount_usdc": 1250, "operation": "debit"},
|
|
235
|
+
]
|
|
236
|
+
for i in range(count):
|
|
237
|
+
base = samples[i % len(samples)]
|
|
238
|
+
data = {
|
|
239
|
+
"id": f"ch_{i}",
|
|
240
|
+
"amount_usdc": base["amount_usdc"],
|
|
241
|
+
"operation": base["operation"],
|
|
242
|
+
"balance_usdc_after": 100_000_000 - base["amount_usdc"] * (i + 1),
|
|
243
|
+
"reason": base["reason"],
|
|
244
|
+
"created_at": f"2026-06-{10 - i:02d}T12:00:00Z",
|
|
245
|
+
}
|
|
246
|
+
obj = MagicMock()
|
|
247
|
+
obj.model_dump = lambda d=data: dict(d)
|
|
248
|
+
for k, v in data.items():
|
|
249
|
+
setattr(obj, k, v)
|
|
250
|
+
entries.append(obj)
|
|
251
|
+
return entries
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""In-package templates for ``teardrop tools init``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# Complete starter template matching CreateOrgToolRequest schema.
|
|
6
|
+
# All fields are explicit --- nullable fields use None so they appear as
|
|
7
|
+
# ``null`` in the output JSON and users discover them early.
|
|
8
|
+
_BASE_TEMPLATE = {
|
|
9
|
+
"name": "{name}",
|
|
10
|
+
"description": "Short one-line summary of what this tool does.",
|
|
11
|
+
"input_schema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"query": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Example input field. Replace with your real schema.",
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": ["query"],
|
|
20
|
+
"additionalProperties": False,
|
|
21
|
+
},
|
|
22
|
+
"output_schema": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"properties": {
|
|
25
|
+
"result": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Example output field. Replace with your real schema.",
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"required": ["result"],
|
|
31
|
+
"additionalProperties": True,
|
|
32
|
+
},
|
|
33
|
+
"webhook_url": "https://example.com/your-webhook-endpoint",
|
|
34
|
+
"webhook_method": "GET",
|
|
35
|
+
"auth_header_name": None,
|
|
36
|
+
"auth_header_value": None,
|
|
37
|
+
"timeout_seconds": 10,
|
|
38
|
+
"publish_as_mcp": False,
|
|
39
|
+
"marketplace_description": None,
|
|
40
|
+
"category": "",
|
|
41
|
+
"base_price_usdc": 0,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def render_tool_template(name: str, *, with_marketplace: bool = False) -> dict:
|
|
46
|
+
"""Return a dict suitable for ``json.dumps`` describing a starter tool."""
|
|
47
|
+
data = {**_BASE_TEMPLATE, "name": name}
|
|
48
|
+
if with_marketplace:
|
|
49
|
+
data["publish_as_mcp"] = True
|
|
50
|
+
data["marketplace_description"] = "One-line marketplace pitch (max 200 characters)."
|
|
51
|
+
return data
|
|
@@ -18,12 +18,16 @@ from teardrop_cli._lazy import LazyGroup
|
|
|
18
18
|
cls=LazyGroup,
|
|
19
19
|
lazy_subcommands={
|
|
20
20
|
"auth": "teardrop_cli.commands.auth:app",
|
|
21
|
+
"chat": "teardrop_cli.commands.chat:app",
|
|
21
22
|
"init": "teardrop_cli.commands.config_cmd:init_app",
|
|
22
23
|
"quickstart": "teardrop_cli.commands.quickstart:app",
|
|
23
24
|
"config": "teardrop_cli.commands.config_cmd:app",
|
|
24
25
|
"run": "teardrop_cli.commands.run:app",
|
|
26
|
+
"schedules": "teardrop_cli.commands.schedules:app",
|
|
25
27
|
"balance": "teardrop_cli.commands.balance:app",
|
|
26
28
|
"usage": "teardrop_cli.commands.usage:app",
|
|
29
|
+
"agent-tools": "teardrop_cli.commands.agent_tools:app",
|
|
30
|
+
"event-triggers": "teardrop_cli.commands.event_triggers:app",
|
|
27
31
|
"marketplace": "teardrop_cli.commands.marketplace:app",
|
|
28
32
|
"tools": "teardrop_cli.commands.tools:app",
|
|
29
33
|
"earnings": "teardrop_cli.commands.earnings:app",
|