autotouch-cli 0.2.17__tar.gz → 0.2.19__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.
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/PKG-INFO +107 -1
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/PKG-INFO +107 -1
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/docs/research-table/reference/autotouch-cli-pypi.md +106 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/pyproject.toml +1 -1
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/smart_table_cli.py +46 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/SOURCES.txt +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/dependency_links.txt +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/entry_points.txt +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/requires.txt +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/autotouch_cli.egg-info/top_level.txt +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/__init__.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/add_column_unique_index.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/attach_csv_import_leads_to_research_table.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/bundle_sequences_backend.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/check_agent_traces.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/check_column_mode.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/exit_terminal_leads_from_sequences.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/fetch_lead.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/fix_lead_titles_from_csv.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250106_add_column_position.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250108_fix_legacy_column_fields.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250109_add_user_fields_to_tables.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250117_add_call_logs_webhook_indexes.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250117_rename_call_logs_collection.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250119_create_leads_unique_email_index.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250123_add_filter_indexes.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250123_add_llm_responses_collection.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250128_migrate_user_ids_to_objectid.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250208_backfill_task_research_values.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250604_add_origin_indexes.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250608_cleanup_agent_metadata.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250608_rename_agent_metadata_to_metadata.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250922_add_activity_indexes.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250926_migrate_single_to_arrays.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250928_add_missing_timestamp_fields.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250929_add_task_join_indexes.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250929_add_task_join_indexes_safe.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250929_create_shared_phone_cache.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20251007_add_rows_position_id_index.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20251109_add_ttl_for_llm_and_preview_traces.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20260113_normalize_table_filter_operators.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20260113_set_user_permissions_user_admin.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20260204_sync_lead_owner_from_tasks.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20260303_add_webhook_subscription_collections.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/migrate_org_user_credits.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/set_default_lead_status.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/update_lead_owner_from_tasks.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/reassign_sequence_owner.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/run_sidecar_orchestrator_demo.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/test_crm_company_policy.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/test_sequences_instantly_e2e.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/test_sequences_personal_e2e.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/test_task_error_logger.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/verify_azurite_voicemail.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/setup.cfg +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_custom.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_integration.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_multi_titles.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_pipeline.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_simple.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_contactout_v2_bulk.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_lead_required_fields.py +0 -0
- {autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/tests/test_phone_provider_pipeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autotouch-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.19
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -140,6 +140,8 @@ Recipe-first flow (recommended):
|
|
|
140
140
|
|
|
141
141
|
```bash
|
|
142
142
|
autotouch columns recipe --type add_to_crm --output human
|
|
143
|
+
autotouch columns recipe --type sync_to_table --output human
|
|
144
|
+
autotouch columns recipe --type add_to_sequence --output human
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
Then create from the generated payload:
|
|
@@ -155,6 +157,44 @@ Notes:
|
|
|
155
157
|
- `add_to_crm` is optional and non-billable.
|
|
156
158
|
- Email/phone enrichment does not require creating/running `add_to_crm`.
|
|
157
159
|
- For `add_to_crm`, required mapping keys are `linkedinUrl` and `companyDomain`.
|
|
160
|
+
- `sync_to_table` supports both:
|
|
161
|
+
- single destination: `destinationTableId` + `columnMappings`
|
|
162
|
+
- router mode: `routes[]` (first matching route wins)
|
|
163
|
+
- `add_to_sequence` requires:
|
|
164
|
+
- `sequenceId`
|
|
165
|
+
- `sourceLeadColumn` pointing to a lead-id producing column (`add_to_crm` or `lead_finder` output)
|
|
166
|
+
- auto-attaches research context defaults during enrollment (`source_table_id`, plus optional table name); favorite fields resolve from current starred columns when explicit `fieldIds` are not provided
|
|
167
|
+
|
|
168
|
+
If you create custom `llm_enrichment` schemas:
|
|
169
|
+
- Use strict field-map schema shape (no root `type/properties` wrapper).
|
|
170
|
+
- Arrays must be explicit `{"type":"array","items":...}`.
|
|
171
|
+
- Avoid legacy/list schema values like `["string"]` or `[{...}]`.
|
|
172
|
+
- Prefer snake_case schema keys in payloads: `response_schema`, `user_schema`, `use_auto_schema`.
|
|
173
|
+
|
|
174
|
+
## Parse enrichment outputs safely (important for agents)
|
|
175
|
+
|
|
176
|
+
Use a layered rule:
|
|
177
|
+
|
|
178
|
+
1. Always inspect raw outputs first (sample at least 3 rows).
|
|
179
|
+
2. Parse by column `dataType`:
|
|
180
|
+
- `json`: use key precedence below.
|
|
181
|
+
- scalar types (`text`, `number`, `date`, `boolean`, `email`, `url`): parse direct value (no JSON key paths).
|
|
182
|
+
3. Only then publish found/missing counts.
|
|
183
|
+
|
|
184
|
+
Do not rely on a single key for JSON outputs.
|
|
185
|
+
|
|
186
|
+
- Phone extraction precedence: `mobile_number` -> `phone_numbers[0].number` -> `primary_phone`
|
|
187
|
+
- Email extraction precedence: `response` -> `email` -> `work_email`
|
|
188
|
+
|
|
189
|
+
If path A is missing, continue to B/C before declaring `not_found`.
|
|
190
|
+
|
|
191
|
+
JSON split note:
|
|
192
|
+
- Optional by default.
|
|
193
|
+
- Use only when downstream filters/mappings need stable flat keys.
|
|
194
|
+
|
|
195
|
+
Reference:
|
|
196
|
+
- `docs/research-table/guides/context-first-sequence-playbook.md`
|
|
197
|
+
- `docs/research-table/reference/runbooks/context-first-sequence.json`
|
|
158
198
|
|
|
159
199
|
## Recommended ICP buyer discovery pattern
|
|
160
200
|
|
|
@@ -187,6 +227,72 @@ Important:
|
|
|
187
227
|
- These workflow routes support `actorUserId` query parameter.
|
|
188
228
|
- External sequence validation rules (manual vs automated vs AI draft constraints) are documented in the workflow reference above.
|
|
189
229
|
|
|
230
|
+
### Sequence step types and rules (quick reference)
|
|
231
|
+
|
|
232
|
+
Supported step kinds:
|
|
233
|
+
- `EMAIL`
|
|
234
|
+
- `CALL`
|
|
235
|
+
- `LINKEDIN`
|
|
236
|
+
- `LINKEDIN_CONNECT`
|
|
237
|
+
- `LINKEDIN_MESSAGE`
|
|
238
|
+
- `CUSTOM`
|
|
239
|
+
|
|
240
|
+
Email send modes:
|
|
241
|
+
- `AUTOMATED`
|
|
242
|
+
- `MANUAL`
|
|
243
|
+
|
|
244
|
+
External API validation rules:
|
|
245
|
+
- First email step cannot be reply (`first_email_reply_not_allowed`).
|
|
246
|
+
- Bulk mode cannot include manual email steps (`bulk_manual_email_not_allowed`).
|
|
247
|
+
- `aiDraft` is only allowed on manual-capable steps:
|
|
248
|
+
- `CALL`, `CUSTOM`, `LINKEDIN`, `LINKEDIN_CONNECT`, `LINKEDIN_MESSAGE`
|
|
249
|
+
- `EMAIL` only when `emailSendMode=MANUAL`
|
|
250
|
+
- `defaultAppendSignature` (sequence-level, optional) sets default signature behavior for email steps.
|
|
251
|
+
- `steps[].appendSignature` (step-level, optional) overrides signature behavior per email step.
|
|
252
|
+
|
|
253
|
+
Runtime behavior:
|
|
254
|
+
- `EMAIL + AUTOMATED` is sent by scheduler/provider flow.
|
|
255
|
+
- Manual/non-automated steps are created as Tasks for rep execution.
|
|
256
|
+
|
|
257
|
+
Minimal mixed-step example:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"name": "Outbound v1",
|
|
262
|
+
"sourceTableId": "tbl_123",
|
|
263
|
+
"defaultAppendSignature": true,
|
|
264
|
+
"steps": [
|
|
265
|
+
{
|
|
266
|
+
"id": "s1",
|
|
267
|
+
"kind": "EMAIL",
|
|
268
|
+
"emailSendMode": "AUTOMATED",
|
|
269
|
+
"emailIsReply": false,
|
|
270
|
+
"appendSignature": true,
|
|
271
|
+
"subjectTemplate": "Quick intro",
|
|
272
|
+
"bodyTemplate": "Hi {{first_name}}, ..."
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "s2",
|
|
276
|
+
"kind": "CALL",
|
|
277
|
+
"waitDays": 2,
|
|
278
|
+
"aiDraft": true
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"id": "s3",
|
|
282
|
+
"kind": "EMAIL",
|
|
283
|
+
"waitDays": 4,
|
|
284
|
+
"emailSendMode": "MANUAL",
|
|
285
|
+
"emailIsReply": false,
|
|
286
|
+
"appendSignature": false,
|
|
287
|
+
"aiDraft": true
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Canonical contract:
|
|
294
|
+
- `docs/platform/external-workflows-api.md`
|
|
295
|
+
|
|
190
296
|
## Outbound webhook subscriptions
|
|
191
297
|
|
|
192
298
|
Use webhook subscriptions to receive customer-facing event notifications.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autotouch-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.19
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Requires-Python: >=3.9
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -140,6 +140,8 @@ Recipe-first flow (recommended):
|
|
|
140
140
|
|
|
141
141
|
```bash
|
|
142
142
|
autotouch columns recipe --type add_to_crm --output human
|
|
143
|
+
autotouch columns recipe --type sync_to_table --output human
|
|
144
|
+
autotouch columns recipe --type add_to_sequence --output human
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
Then create from the generated payload:
|
|
@@ -155,6 +157,44 @@ Notes:
|
|
|
155
157
|
- `add_to_crm` is optional and non-billable.
|
|
156
158
|
- Email/phone enrichment does not require creating/running `add_to_crm`.
|
|
157
159
|
- For `add_to_crm`, required mapping keys are `linkedinUrl` and `companyDomain`.
|
|
160
|
+
- `sync_to_table` supports both:
|
|
161
|
+
- single destination: `destinationTableId` + `columnMappings`
|
|
162
|
+
- router mode: `routes[]` (first matching route wins)
|
|
163
|
+
- `add_to_sequence` requires:
|
|
164
|
+
- `sequenceId`
|
|
165
|
+
- `sourceLeadColumn` pointing to a lead-id producing column (`add_to_crm` or `lead_finder` output)
|
|
166
|
+
- auto-attaches research context defaults during enrollment (`source_table_id`, plus optional table name); favorite fields resolve from current starred columns when explicit `fieldIds` are not provided
|
|
167
|
+
|
|
168
|
+
If you create custom `llm_enrichment` schemas:
|
|
169
|
+
- Use strict field-map schema shape (no root `type/properties` wrapper).
|
|
170
|
+
- Arrays must be explicit `{"type":"array","items":...}`.
|
|
171
|
+
- Avoid legacy/list schema values like `["string"]` or `[{...}]`.
|
|
172
|
+
- Prefer snake_case schema keys in payloads: `response_schema`, `user_schema`, `use_auto_schema`.
|
|
173
|
+
|
|
174
|
+
## Parse enrichment outputs safely (important for agents)
|
|
175
|
+
|
|
176
|
+
Use a layered rule:
|
|
177
|
+
|
|
178
|
+
1. Always inspect raw outputs first (sample at least 3 rows).
|
|
179
|
+
2. Parse by column `dataType`:
|
|
180
|
+
- `json`: use key precedence below.
|
|
181
|
+
- scalar types (`text`, `number`, `date`, `boolean`, `email`, `url`): parse direct value (no JSON key paths).
|
|
182
|
+
3. Only then publish found/missing counts.
|
|
183
|
+
|
|
184
|
+
Do not rely on a single key for JSON outputs.
|
|
185
|
+
|
|
186
|
+
- Phone extraction precedence: `mobile_number` -> `phone_numbers[0].number` -> `primary_phone`
|
|
187
|
+
- Email extraction precedence: `response` -> `email` -> `work_email`
|
|
188
|
+
|
|
189
|
+
If path A is missing, continue to B/C before declaring `not_found`.
|
|
190
|
+
|
|
191
|
+
JSON split note:
|
|
192
|
+
- Optional by default.
|
|
193
|
+
- Use only when downstream filters/mappings need stable flat keys.
|
|
194
|
+
|
|
195
|
+
Reference:
|
|
196
|
+
- `docs/research-table/guides/context-first-sequence-playbook.md`
|
|
197
|
+
- `docs/research-table/reference/runbooks/context-first-sequence.json`
|
|
158
198
|
|
|
159
199
|
## Recommended ICP buyer discovery pattern
|
|
160
200
|
|
|
@@ -187,6 +227,72 @@ Important:
|
|
|
187
227
|
- These workflow routes support `actorUserId` query parameter.
|
|
188
228
|
- External sequence validation rules (manual vs automated vs AI draft constraints) are documented in the workflow reference above.
|
|
189
229
|
|
|
230
|
+
### Sequence step types and rules (quick reference)
|
|
231
|
+
|
|
232
|
+
Supported step kinds:
|
|
233
|
+
- `EMAIL`
|
|
234
|
+
- `CALL`
|
|
235
|
+
- `LINKEDIN`
|
|
236
|
+
- `LINKEDIN_CONNECT`
|
|
237
|
+
- `LINKEDIN_MESSAGE`
|
|
238
|
+
- `CUSTOM`
|
|
239
|
+
|
|
240
|
+
Email send modes:
|
|
241
|
+
- `AUTOMATED`
|
|
242
|
+
- `MANUAL`
|
|
243
|
+
|
|
244
|
+
External API validation rules:
|
|
245
|
+
- First email step cannot be reply (`first_email_reply_not_allowed`).
|
|
246
|
+
- Bulk mode cannot include manual email steps (`bulk_manual_email_not_allowed`).
|
|
247
|
+
- `aiDraft` is only allowed on manual-capable steps:
|
|
248
|
+
- `CALL`, `CUSTOM`, `LINKEDIN`, `LINKEDIN_CONNECT`, `LINKEDIN_MESSAGE`
|
|
249
|
+
- `EMAIL` only when `emailSendMode=MANUAL`
|
|
250
|
+
- `defaultAppendSignature` (sequence-level, optional) sets default signature behavior for email steps.
|
|
251
|
+
- `steps[].appendSignature` (step-level, optional) overrides signature behavior per email step.
|
|
252
|
+
|
|
253
|
+
Runtime behavior:
|
|
254
|
+
- `EMAIL + AUTOMATED` is sent by scheduler/provider flow.
|
|
255
|
+
- Manual/non-automated steps are created as Tasks for rep execution.
|
|
256
|
+
|
|
257
|
+
Minimal mixed-step example:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"name": "Outbound v1",
|
|
262
|
+
"sourceTableId": "tbl_123",
|
|
263
|
+
"defaultAppendSignature": true,
|
|
264
|
+
"steps": [
|
|
265
|
+
{
|
|
266
|
+
"id": "s1",
|
|
267
|
+
"kind": "EMAIL",
|
|
268
|
+
"emailSendMode": "AUTOMATED",
|
|
269
|
+
"emailIsReply": false,
|
|
270
|
+
"appendSignature": true,
|
|
271
|
+
"subjectTemplate": "Quick intro",
|
|
272
|
+
"bodyTemplate": "Hi {{first_name}}, ..."
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "s2",
|
|
276
|
+
"kind": "CALL",
|
|
277
|
+
"waitDays": 2,
|
|
278
|
+
"aiDraft": true
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"id": "s3",
|
|
282
|
+
"kind": "EMAIL",
|
|
283
|
+
"waitDays": 4,
|
|
284
|
+
"emailSendMode": "MANUAL",
|
|
285
|
+
"emailIsReply": false,
|
|
286
|
+
"appendSignature": false,
|
|
287
|
+
"aiDraft": true
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Canonical contract:
|
|
294
|
+
- `docs/platform/external-workflows-api.md`
|
|
295
|
+
|
|
190
296
|
## Outbound webhook subscriptions
|
|
191
297
|
|
|
192
298
|
Use webhook subscriptions to receive customer-facing event notifications.
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/docs/research-table/reference/autotouch-cli-pypi.md
RENAMED
|
@@ -131,6 +131,8 @@ Recipe-first flow (recommended):
|
|
|
131
131
|
|
|
132
132
|
```bash
|
|
133
133
|
autotouch columns recipe --type add_to_crm --output human
|
|
134
|
+
autotouch columns recipe --type sync_to_table --output human
|
|
135
|
+
autotouch columns recipe --type add_to_sequence --output human
|
|
134
136
|
```
|
|
135
137
|
|
|
136
138
|
Then create from the generated payload:
|
|
@@ -146,6 +148,44 @@ Notes:
|
|
|
146
148
|
- `add_to_crm` is optional and non-billable.
|
|
147
149
|
- Email/phone enrichment does not require creating/running `add_to_crm`.
|
|
148
150
|
- For `add_to_crm`, required mapping keys are `linkedinUrl` and `companyDomain`.
|
|
151
|
+
- `sync_to_table` supports both:
|
|
152
|
+
- single destination: `destinationTableId` + `columnMappings`
|
|
153
|
+
- router mode: `routes[]` (first matching route wins)
|
|
154
|
+
- `add_to_sequence` requires:
|
|
155
|
+
- `sequenceId`
|
|
156
|
+
- `sourceLeadColumn` pointing to a lead-id producing column (`add_to_crm` or `lead_finder` output)
|
|
157
|
+
- auto-attaches research context defaults during enrollment (`source_table_id`, plus optional table name); favorite fields resolve from current starred columns when explicit `fieldIds` are not provided
|
|
158
|
+
|
|
159
|
+
If you create custom `llm_enrichment` schemas:
|
|
160
|
+
- Use strict field-map schema shape (no root `type/properties` wrapper).
|
|
161
|
+
- Arrays must be explicit `{"type":"array","items":...}`.
|
|
162
|
+
- Avoid legacy/list schema values like `["string"]` or `[{...}]`.
|
|
163
|
+
- Prefer snake_case schema keys in payloads: `response_schema`, `user_schema`, `use_auto_schema`.
|
|
164
|
+
|
|
165
|
+
## Parse enrichment outputs safely (important for agents)
|
|
166
|
+
|
|
167
|
+
Use a layered rule:
|
|
168
|
+
|
|
169
|
+
1. Always inspect raw outputs first (sample at least 3 rows).
|
|
170
|
+
2. Parse by column `dataType`:
|
|
171
|
+
- `json`: use key precedence below.
|
|
172
|
+
- scalar types (`text`, `number`, `date`, `boolean`, `email`, `url`): parse direct value (no JSON key paths).
|
|
173
|
+
3. Only then publish found/missing counts.
|
|
174
|
+
|
|
175
|
+
Do not rely on a single key for JSON outputs.
|
|
176
|
+
|
|
177
|
+
- Phone extraction precedence: `mobile_number` -> `phone_numbers[0].number` -> `primary_phone`
|
|
178
|
+
- Email extraction precedence: `response` -> `email` -> `work_email`
|
|
179
|
+
|
|
180
|
+
If path A is missing, continue to B/C before declaring `not_found`.
|
|
181
|
+
|
|
182
|
+
JSON split note:
|
|
183
|
+
- Optional by default.
|
|
184
|
+
- Use only when downstream filters/mappings need stable flat keys.
|
|
185
|
+
|
|
186
|
+
Reference:
|
|
187
|
+
- `docs/research-table/guides/context-first-sequence-playbook.md`
|
|
188
|
+
- `docs/research-table/reference/runbooks/context-first-sequence.json`
|
|
149
189
|
|
|
150
190
|
## Recommended ICP buyer discovery pattern
|
|
151
191
|
|
|
@@ -178,6 +218,72 @@ Important:
|
|
|
178
218
|
- These workflow routes support `actorUserId` query parameter.
|
|
179
219
|
- External sequence validation rules (manual vs automated vs AI draft constraints) are documented in the workflow reference above.
|
|
180
220
|
|
|
221
|
+
### Sequence step types and rules (quick reference)
|
|
222
|
+
|
|
223
|
+
Supported step kinds:
|
|
224
|
+
- `EMAIL`
|
|
225
|
+
- `CALL`
|
|
226
|
+
- `LINKEDIN`
|
|
227
|
+
- `LINKEDIN_CONNECT`
|
|
228
|
+
- `LINKEDIN_MESSAGE`
|
|
229
|
+
- `CUSTOM`
|
|
230
|
+
|
|
231
|
+
Email send modes:
|
|
232
|
+
- `AUTOMATED`
|
|
233
|
+
- `MANUAL`
|
|
234
|
+
|
|
235
|
+
External API validation rules:
|
|
236
|
+
- First email step cannot be reply (`first_email_reply_not_allowed`).
|
|
237
|
+
- Bulk mode cannot include manual email steps (`bulk_manual_email_not_allowed`).
|
|
238
|
+
- `aiDraft` is only allowed on manual-capable steps:
|
|
239
|
+
- `CALL`, `CUSTOM`, `LINKEDIN`, `LINKEDIN_CONNECT`, `LINKEDIN_MESSAGE`
|
|
240
|
+
- `EMAIL` only when `emailSendMode=MANUAL`
|
|
241
|
+
- `defaultAppendSignature` (sequence-level, optional) sets default signature behavior for email steps.
|
|
242
|
+
- `steps[].appendSignature` (step-level, optional) overrides signature behavior per email step.
|
|
243
|
+
|
|
244
|
+
Runtime behavior:
|
|
245
|
+
- `EMAIL + AUTOMATED` is sent by scheduler/provider flow.
|
|
246
|
+
- Manual/non-automated steps are created as Tasks for rep execution.
|
|
247
|
+
|
|
248
|
+
Minimal mixed-step example:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"name": "Outbound v1",
|
|
253
|
+
"sourceTableId": "tbl_123",
|
|
254
|
+
"defaultAppendSignature": true,
|
|
255
|
+
"steps": [
|
|
256
|
+
{
|
|
257
|
+
"id": "s1",
|
|
258
|
+
"kind": "EMAIL",
|
|
259
|
+
"emailSendMode": "AUTOMATED",
|
|
260
|
+
"emailIsReply": false,
|
|
261
|
+
"appendSignature": true,
|
|
262
|
+
"subjectTemplate": "Quick intro",
|
|
263
|
+
"bodyTemplate": "Hi {{first_name}}, ..."
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"id": "s2",
|
|
267
|
+
"kind": "CALL",
|
|
268
|
+
"waitDays": 2,
|
|
269
|
+
"aiDraft": true
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"id": "s3",
|
|
273
|
+
"kind": "EMAIL",
|
|
274
|
+
"waitDays": 4,
|
|
275
|
+
"emailSendMode": "MANUAL",
|
|
276
|
+
"emailIsReply": false,
|
|
277
|
+
"appendSignature": false,
|
|
278
|
+
"aiDraft": true
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Canonical contract:
|
|
285
|
+
- `docs/platform/external-workflows-api.md`
|
|
286
|
+
|
|
181
287
|
## Outbound webhook subscriptions
|
|
182
288
|
|
|
183
289
|
Use webhook subscriptions to receive customer-facing event notifications.
|
|
@@ -77,6 +77,8 @@ COLUMN_RECIPE_TYPES = [
|
|
|
77
77
|
"lead_finder",
|
|
78
78
|
"llm_enrichment",
|
|
79
79
|
"add_to_crm",
|
|
80
|
+
"sync_to_table",
|
|
81
|
+
"add_to_sequence",
|
|
80
82
|
]
|
|
81
83
|
|
|
82
84
|
COLUMN_CREATE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
@@ -181,6 +183,36 @@ COLUMN_CREATE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
|
181
183
|
],
|
|
182
184
|
},
|
|
183
185
|
},
|
|
186
|
+
"sync_to_table": {
|
|
187
|
+
"key": "sync_to_table",
|
|
188
|
+
"label": "Sync to Table",
|
|
189
|
+
"kind": "enrichment",
|
|
190
|
+
"dataType": "json",
|
|
191
|
+
"origin": "manual",
|
|
192
|
+
"autoRun": "onSourceUpdate",
|
|
193
|
+
"config": {
|
|
194
|
+
"provider": "sync_to_table",
|
|
195
|
+
"destinationTableId": "<DESTINATION_TABLE_ID>",
|
|
196
|
+
"columnMappings": [
|
|
197
|
+
{"sourceKey": "company", "destKey": "company"},
|
|
198
|
+
{"sourceKey": "domain", "destKey": "company_domain"},
|
|
199
|
+
{"sourceKey": "work_email", "destKey": "work_email"},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
"add_to_sequence": {
|
|
204
|
+
"key": "add_to_sequence",
|
|
205
|
+
"label": "Add to Sequence",
|
|
206
|
+
"kind": "enrichment",
|
|
207
|
+
"dataType": "json",
|
|
208
|
+
"origin": "manual",
|
|
209
|
+
"autoRun": "onSourceUpdate",
|
|
210
|
+
"config": {
|
|
211
|
+
"provider": "add_to_sequence",
|
|
212
|
+
"sequenceId": "<SEQUENCE_ID>",
|
|
213
|
+
"sourceLeadColumn": "add_to_leads",
|
|
214
|
+
},
|
|
215
|
+
},
|
|
184
216
|
}
|
|
185
217
|
|
|
186
218
|
COLUMN_RECIPE_NOTES: Dict[str, List[str]] = {
|
|
@@ -201,21 +233,35 @@ COLUMN_RECIPE_NOTES: Dict[str, List[str]] = {
|
|
|
201
233
|
"LinkedIn URL + company domain mappings are required for eligibility.",
|
|
202
234
|
"Add to CRM is optional and non-billable.",
|
|
203
235
|
],
|
|
236
|
+
"sync_to_table": [
|
|
237
|
+
"Use destinationTableId + columnMappings for single-destination sync.",
|
|
238
|
+
"Router mode is supported via config.routes[] (first matching route wins).",
|
|
239
|
+
],
|
|
240
|
+
"add_to_sequence": [
|
|
241
|
+
"sourceLeadColumn should reference a column that stores lead IDs (for example add_to_crm or lead_finder output).",
|
|
242
|
+
"Set sequenceId to the target workflow sequence ID.",
|
|
243
|
+
],
|
|
204
244
|
}
|
|
205
245
|
|
|
206
246
|
RUN_SOP_GUIDE: Dict[str, Any] = {
|
|
207
247
|
"title": "Credit-safe enrichment SOP",
|
|
208
248
|
"rules": [
|
|
249
|
+
"Use --output json for automation; avoid parsing human-format output.",
|
|
209
250
|
"Filter first before running billable columns.",
|
|
210
251
|
"Estimate first with the same payload you plan to run.",
|
|
211
252
|
"Start with a small firstN pilot before scaling.",
|
|
212
253
|
"For exact bounded batches, prefer run-next with a small count.",
|
|
213
254
|
"For add_to_crm, generate payload from columns recipe before create/update.",
|
|
214
255
|
"Keep unprocessedOnly enabled unless you intentionally reprocess rows.",
|
|
256
|
+
"Treat bulk job state as source of truth: queued/distributing/processing are non-terminal; completed/partial/error/cancelled are terminal.",
|
|
257
|
+
"Always inspect raw outputs before summary counts; parse by column dataType (json vs scalar).",
|
|
258
|
+
"When summarizing enrichment outputs, parse by key precedence (phone: mobile_number -> phone_numbers[0].number -> primary_phone; email: response -> email -> work_email).",
|
|
215
259
|
],
|
|
216
260
|
"clarifications": [
|
|
217
261
|
"Email/phone enrichment does not require add_to_crm.",
|
|
218
262
|
"add_to_crm is an optional export action to Leads CRM (non-billable).",
|
|
263
|
+
"For custom LLM schemas, use strict field-map shape (no root type/properties wrapper; arrays must use {type:\"array\",items:...}).",
|
|
264
|
+
"Do not report not_found from a single missing key when fallback keys exist.",
|
|
219
265
|
],
|
|
220
266
|
"default_run_payload": {
|
|
221
267
|
"scope": "filtered",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/attach_csv_import_leads_to_research_table.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250106_add_column_position.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250123_add_filter_indexes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250604_add_origin_indexes.py
RENAMED
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250608_cleanup_agent_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250922_add_activity_indexes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/20250929_add_task_join_indexes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/migrate_org_user_credits.py
RENAMED
|
File without changes
|
|
File without changes
|
{autotouch_cli-0.2.17 → autotouch_cli-0.2.19}/scripts/migrations/update_lead_owner_from_tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|