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.
Files changed (77) hide show
  1. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/PKG-INFO +80 -8
  2. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/README.md +78 -6
  3. teardrop_cli-0.3.0/docs/cli-json-schema.md +130 -0
  4. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/docs/cli-reference.md +100 -2
  5. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/pyproject.toml +2 -2
  6. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/_fixtures.py +57 -3
  7. teardrop_cli-0.3.0/src/teardrop_cli/_templates.py +51 -0
  8. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/cli.py +4 -0
  9. teardrop_cli-0.3.0/src/teardrop_cli/commands/agent_tools.py +90 -0
  10. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/auth.py +188 -43
  11. teardrop_cli-0.3.0/src/teardrop_cli/commands/balance.py +201 -0
  12. teardrop_cli-0.3.0/src/teardrop_cli/commands/chat.py +175 -0
  13. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/config_cmd.py +1 -3
  14. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/earnings.py +33 -19
  15. teardrop_cli-0.3.0/src/teardrop_cli/commands/event_triggers.py +457 -0
  16. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/llm_config.py +7 -13
  17. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/marketplace.py +57 -27
  18. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/models.py +4 -2
  19. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/quickstart.py +33 -67
  20. teardrop_cli-0.3.0/src/teardrop_cli/commands/run.py +371 -0
  21. teardrop_cli-0.3.0/src/teardrop_cli/commands/schedules.py +386 -0
  22. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/tools.py +38 -26
  23. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/config.py +153 -4
  24. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/formatting.py +162 -36
  25. teardrop_cli-0.3.0/src/teardrop_cli/pricing.py +264 -0
  26. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/conftest.py +129 -1
  27. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/conftest.py +1 -4
  28. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_auth_e2e.py +2 -8
  29. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_billing_e2e.py +13 -3
  30. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_marketplace_e2e.py +3 -9
  31. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_signup_e2e.py +4 -11
  32. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_siwe_login_e2e.py +3 -9
  33. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_auth.py +51 -17
  34. teardrop_cli-0.3.0/tests/test_billing.py +73 -0
  35. teardrop_cli-0.3.0/tests/test_chat.py +230 -0
  36. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_credential_priority.py +67 -8
  37. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_earnings.py +2 -6
  38. teardrop_cli-0.3.0/tests/test_event_triggers.py +240 -0
  39. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_init_and_byok.py +88 -15
  40. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_llm_config.py +3 -9
  41. teardrop_cli-0.3.0/tests/test_marketplace.py +129 -0
  42. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_models.py +4 -4
  43. teardrop_cli-0.3.0/tests/test_quickstart.py +218 -0
  44. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_run.py +61 -10
  45. teardrop_cli-0.3.0/tests/test_schedules.py +217 -0
  46. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_signup.py +5 -15
  47. teardrop_cli-0.3.0/tests/test_token_expiry_fallback.py +133 -0
  48. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_tools.py +7 -21
  49. teardrop_cli-0.1.1/docs/cli-json-schema.md +0 -25
  50. teardrop_cli-0.1.1/src/teardrop_cli/_templates.py +0 -37
  51. teardrop_cli-0.1.1/src/teardrop_cli/commands/balance.py +0 -74
  52. teardrop_cli-0.1.1/src/teardrop_cli/commands/run.py +0 -189
  53. teardrop_cli-0.1.1/tests/test_billing.py +0 -39
  54. teardrop_cli-0.1.1/tests/test_marketplace.py +0 -80
  55. teardrop_cli-0.1.1/tests/test_quickstart.py +0 -178
  56. teardrop_cli-0.1.1/tests/test_token_expiry_fallback.py +0 -62
  57. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.github/workflows/publish.yml +0 -0
  58. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.github/workflows/test.yml +0 -0
  59. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.gitignore +0 -0
  60. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/.vscode/settings.json +0 -0
  61. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/LICENSE +0 -0
  62. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/__init__.py +0 -0
  63. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/_lazy.py +0 -0
  64. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/__init__.py +0 -0
  65. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/mcp.py +0 -0
  66. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/usage.py +0 -0
  67. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/README.md +0 -0
  68. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/__init__.py +0 -0
  69. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/e2e/test_run_e2e.py +0 -0
  70. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/__init__.py +0 -0
  71. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/conftest.py +0 -0
  72. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_config_persistence.py +0 -0
  73. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_keyring_integration.py +0 -0
  74. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_perf_lazygroup.py +0 -0
  75. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/smoke/test_siwe_signing.py +0 -0
  76. {teardrop_cli-0.1.1 → teardrop_cli-0.3.0}/tests/test_config_cmd.py +0 -0
  77. {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.1.1
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.1.5
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
- | Sign in with wallet (existing key) | `teardrop auth login --siwe --key-file wallet.key` |
122
- | Generate a new wallet & sign in | `teardrop auth login --siwe --generate-wallet` |
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. Sessions are stored in your OS keyring.
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
- If a run fails on credit, top up via the dashboard:
209
+ ## Automate Runs
210
+
211
+ Use interval schedules for recurring prompts and event triggers for inbound webhooks:
194
212
 
195
213
  ```bash
196
- teardrop balance # check credits
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
- | Sign in with wallet (existing key) | `teardrop auth login --siwe --key-file wallet.key` |
62
- | Generate a new wallet & sign in | `teardrop auth login --siwe --generate-wallet` |
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. Sessions are stored in your OS keyring.
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
- If a run fails on credit, top up via the dashboard:
149
+ ## Automate Runs
150
+
151
+ Use interval schedules for recurring prompts and event triggers for inbound webhooks:
134
152
 
135
153
  ```bash
136
- teardrop balance # check credits
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.1.1"
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.1.5",
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.08,
180
- "tokens_out_cost_per_1k": 0.24,
181
- "tool_call_cost": 0.0,
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",