autotouch-cli 0.2.92__tar.gz → 0.2.94__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.92 → autotouch_cli-0.2.94}/PKG-INFO +2 -2
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/README.md +1 -1
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/cli.py +2 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/agents.py +123 -1
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/sequences.py +69 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/data/CLI_REFERENCE.md +42 -11
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/data/cli-manifest.json +227 -4
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/parser.py +1 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/templates.py +14 -13
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/PKG-INFO +2 -2
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/pyproject.toml +1 -1
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/MANIFEST.in +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/__init__.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/cli_contracts.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/__init__.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/auth.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/cells.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/columns.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/jobs.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/leads.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/linkedin.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/list_build.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/prompts.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/rows.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/search.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/tables.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/tasks.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/webhooks.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/commands/workspace_secrets.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/__init__.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/auth.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/config.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/csv_import.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/http.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/io.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/output.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/polling.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/run.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/core/validation.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/exceptions.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/mongo_status.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/parser_groups.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli/sequence_support.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/SOURCES.txt +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/dependency_links.txt +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/entry_points.txt +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/requires.txt +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_cli.egg-info/top_level.txt +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/__init__.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/linkedin_contract.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/linkedin_filters.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/list_build_contract.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/provider_registry.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/autotouch_shared/search_contract.py +0 -0
- {autotouch_cli-0.2.92 → autotouch_cli-0.2.94}/setup.cfg +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.94
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Project-URL: Homepage, https://app.autotouch.ai
|
|
6
6
|
Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
|
|
@@ -178,7 +178,7 @@ For automation or agent-driven setup, use:
|
|
|
178
178
|
- `autotouch cli-manifest --output json` for the local machine-readable command contract
|
|
179
179
|
- `autotouch cli-reference` for the shipped parser-generated reference
|
|
180
180
|
- `autotouch capabilities --output json` for provider/workflow contracts
|
|
181
|
-
- `autotouch --version` should be `0.2.
|
|
181
|
+
- `autotouch --version` should be `0.2.94` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, and research-table sequence handoff assignee config
|
|
182
182
|
- `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
|
|
183
183
|
- `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
|
|
184
184
|
- `autotouch list-build companies` and `autotouch list-build leads` for durable LinkedIn-sourced company and lead list builds with Smart Table-owned background workers, visible progress, and no user-owned LinkedIn connection requirement
|
|
@@ -153,7 +153,7 @@ For automation or agent-driven setup, use:
|
|
|
153
153
|
- `autotouch cli-manifest --output json` for the local machine-readable command contract
|
|
154
154
|
- `autotouch cli-reference` for the shipped parser-generated reference
|
|
155
155
|
- `autotouch capabilities --output json` for provider/workflow contracts
|
|
156
|
-
- `autotouch --version` should be `0.2.
|
|
156
|
+
- `autotouch --version` should be `0.2.94` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, and research-table sequence handoff assignee config
|
|
157
157
|
- `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
|
|
158
158
|
- `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
|
|
159
159
|
- `autotouch list-build companies` and `autotouch list-build leads` for durable LinkedIn-sourced company and lead list builds with Smart Table-owned background workers, visible progress, and no user-owned LinkedIn connection requirement
|
|
@@ -141,6 +141,7 @@ from autotouch_cli.commands.agents import (
|
|
|
141
141
|
cmd_agents_get as cmd_agents_get_impl,
|
|
142
142
|
cmd_agents_create as cmd_agents_create_impl,
|
|
143
143
|
cmd_agents_update as cmd_agents_update_impl,
|
|
144
|
+
cmd_agents_diff as cmd_agents_diff_impl,
|
|
144
145
|
cmd_agents_delete as cmd_agents_delete_impl,
|
|
145
146
|
cmd_agents_run as cmd_agents_run_impl,
|
|
146
147
|
cmd_agents_runs as cmd_agents_runs_impl,
|
|
@@ -1478,6 +1479,7 @@ _register("agents_list", cmd_agents_list_impl, _agent_command_runtime)
|
|
|
1478
1479
|
_register("agents_get", cmd_agents_get_impl, _agent_command_runtime)
|
|
1479
1480
|
_register("agents_create", cmd_agents_create_impl, _agent_command_runtime)
|
|
1480
1481
|
_register("agents_update", cmd_agents_update_impl, _agent_command_runtime)
|
|
1482
|
+
_register("agents_diff", cmd_agents_diff_impl, _agent_command_runtime)
|
|
1481
1483
|
_register("agents_delete", cmd_agents_delete_impl, _agent_command_runtime)
|
|
1482
1484
|
_register("agents_run", cmd_agents_run_impl, _agent_command_runtime)
|
|
1483
1485
|
_register("agents_runs", cmd_agents_runs_impl, _agent_command_runtime)
|
|
@@ -3,17 +3,32 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
|
+
import difflib
|
|
6
7
|
import json
|
|
7
8
|
import sys
|
|
8
9
|
import time
|
|
9
10
|
from dataclasses import dataclass
|
|
10
|
-
from typing import Any, Callable, Dict, Optional, Sequence
|
|
11
|
+
from typing import Any, Callable, Dict, List, Optional, Sequence
|
|
11
12
|
|
|
12
13
|
from autotouch_cli.exceptions import AutotouchInputError
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
AGENT_TARGET_CHOICES = ["LEADS", "ACCOUNTS"]
|
|
16
17
|
|
|
18
|
+
AGENT_READ_ONLY_FIELDS = {
|
|
19
|
+
"id",
|
|
20
|
+
"configVersion",
|
|
21
|
+
"createdAt",
|
|
22
|
+
"updatedAt",
|
|
23
|
+
"nextRunAt",
|
|
24
|
+
"lastRunAt",
|
|
25
|
+
"sourceTableName",
|
|
26
|
+
"outputTableName",
|
|
27
|
+
"leadCounts",
|
|
28
|
+
"outputCounts",
|
|
29
|
+
"qualifiedColumnId",
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
|
|
18
33
|
@dataclass(frozen=True)
|
|
19
34
|
class AgentCommandRuntime:
|
|
@@ -29,6 +44,76 @@ class AgentCommandRuntime:
|
|
|
29
44
|
# CRUD
|
|
30
45
|
# ---------------------------------------------------------------------------
|
|
31
46
|
|
|
47
|
+
def _write_json_file(path: str, data: Any) -> None:
|
|
48
|
+
with open(path, "w", encoding="utf-8") as handle:
|
|
49
|
+
json.dump(data, handle, indent=2, ensure_ascii=False)
|
|
50
|
+
handle.write("\n")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _editable_agent_payload(agent: Dict[str, Any]) -> Dict[str, Any]:
|
|
54
|
+
return {key: value for key, value in agent.items() if key not in AGENT_READ_ONLY_FIELDS}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _json_lines(data: Any) -> List[str]:
|
|
58
|
+
return json.dumps(data, indent=2, sort_keys=True, ensure_ascii=False).splitlines()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _diff_payload(current: Dict[str, Any], patch: Dict[str, Any]) -> Dict[str, Any]:
|
|
62
|
+
before = {key: current.get(key) for key in patch.keys()}
|
|
63
|
+
after = dict(before)
|
|
64
|
+
after.update(patch)
|
|
65
|
+
changes = [
|
|
66
|
+
{"field": key, "before": before.get(key), "after": after.get(key)}
|
|
67
|
+
for key in sorted(patch.keys())
|
|
68
|
+
if before.get(key) != after.get(key)
|
|
69
|
+
]
|
|
70
|
+
unified_diff = "\n".join(
|
|
71
|
+
difflib.unified_diff(
|
|
72
|
+
_json_lines(before),
|
|
73
|
+
_json_lines(after),
|
|
74
|
+
fromfile="current",
|
|
75
|
+
tofile="proposed",
|
|
76
|
+
lineterm="",
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
return {"changed": bool(changes), "changes": changes, "diff": unified_diff}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _diff_from_agents(current: Dict[str, Any], proposed: Dict[str, Any], fields: Sequence[str]) -> Dict[str, Any]:
|
|
83
|
+
before = {key: current.get(key) for key in fields}
|
|
84
|
+
after = {key: proposed.get(key) for key in fields}
|
|
85
|
+
changes = [
|
|
86
|
+
{"field": key, "before": before.get(key), "after": after.get(key)}
|
|
87
|
+
for key in sorted(fields)
|
|
88
|
+
if before.get(key) != after.get(key)
|
|
89
|
+
]
|
|
90
|
+
unified_diff = "\n".join(
|
|
91
|
+
difflib.unified_diff(
|
|
92
|
+
_json_lines(before),
|
|
93
|
+
_json_lines(after),
|
|
94
|
+
fromfile="current",
|
|
95
|
+
tofile="proposed",
|
|
96
|
+
lineterm="",
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
return {"changed": bool(changes), "changes": changes, "diff": unified_diff}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _validate_update_remote(args: argparse.Namespace, payload: Dict[str, Any], *, runtime: AgentCommandRuntime, token: Optional[str]) -> Dict[str, Any]:
|
|
103
|
+
data = runtime.request_api(
|
|
104
|
+
"POST", f"/api/agents/{args.agent_id}/validate-update",
|
|
105
|
+
base_url=args.base_url, token=token,
|
|
106
|
+
use_x_api_key=args.use_x_api_key,
|
|
107
|
+
payload=payload,
|
|
108
|
+
timeout=args.timeout, verbose=args.verbose,
|
|
109
|
+
)
|
|
110
|
+
if not isinstance(data, dict):
|
|
111
|
+
raise AutotouchInputError("agent update validation response must be a JSON object")
|
|
112
|
+
fields = data.get("changedFields") or []
|
|
113
|
+
if isinstance(fields, list) and isinstance(data.get("currentAgent"), dict) and isinstance(data.get("agent"), dict):
|
|
114
|
+
data.update(_diff_from_agents(data["currentAgent"], data["agent"], [str(field) for field in fields]))
|
|
115
|
+
return data
|
|
116
|
+
|
|
32
117
|
def cmd_agents_list(args: argparse.Namespace, *, runtime: AgentCommandRuntime) -> None:
|
|
33
118
|
token = runtime.resolve_token(args.token, required=True)
|
|
34
119
|
data = runtime.request_api(
|
|
@@ -48,6 +133,10 @@ def cmd_agents_get(args: argparse.Namespace, *, runtime: AgentCommandRuntime) ->
|
|
|
48
133
|
use_x_api_key=args.use_x_api_key,
|
|
49
134
|
timeout=args.timeout, verbose=args.verbose,
|
|
50
135
|
)
|
|
136
|
+
out_file = getattr(args, "out_file", None)
|
|
137
|
+
if out_file:
|
|
138
|
+
payload = _editable_agent_payload(data if isinstance(data, dict) else {})
|
|
139
|
+
_write_json_file(out_file, payload)
|
|
51
140
|
runtime.print_json(data, args.compact)
|
|
52
141
|
|
|
53
142
|
|
|
@@ -258,6 +347,14 @@ def cmd_agents_update(args: argparse.Namespace, *, runtime: AgentCommandRuntime)
|
|
|
258
347
|
merged_schedule[key] = value
|
|
259
348
|
payload["schedule"] = merged_schedule
|
|
260
349
|
|
|
350
|
+
if getattr(args, "dry_run", False):
|
|
351
|
+
data = _validate_update_remote(args, payload, runtime=runtime, token=token)
|
|
352
|
+
data.setdefault("dryRun", True)
|
|
353
|
+
data.setdefault("patch", payload)
|
|
354
|
+
data.setdefault("next", "Run again without --dry-run to apply this patch.")
|
|
355
|
+
runtime.print_json(data, args.compact)
|
|
356
|
+
return
|
|
357
|
+
|
|
261
358
|
data = runtime.request_api(
|
|
262
359
|
"PATCH", f"/api/agents/{args.agent_id}",
|
|
263
360
|
base_url=args.base_url, token=token,
|
|
@@ -268,6 +365,22 @@ def cmd_agents_update(args: argparse.Namespace, *, runtime: AgentCommandRuntime)
|
|
|
268
365
|
runtime.print_json(data, args.compact)
|
|
269
366
|
|
|
270
367
|
|
|
368
|
+
def cmd_agents_diff(args: argparse.Namespace, *, runtime: AgentCommandRuntime) -> None:
|
|
369
|
+
token = runtime.resolve_token(args.token, required=True)
|
|
370
|
+
patch = runtime.load_json_input(
|
|
371
|
+
inline_json=None,
|
|
372
|
+
file_path=args.from_file,
|
|
373
|
+
context="agent patch",
|
|
374
|
+
default={},
|
|
375
|
+
)
|
|
376
|
+
if not isinstance(patch, dict):
|
|
377
|
+
raise AutotouchInputError("agent patch must be a JSON object")
|
|
378
|
+
result = _validate_update_remote(args, patch, runtime=runtime, token=token)
|
|
379
|
+
result.setdefault("agentId", args.agent_id)
|
|
380
|
+
result.setdefault("patch", patch)
|
|
381
|
+
runtime.print_json(result, args.compact)
|
|
382
|
+
|
|
383
|
+
|
|
271
384
|
def cmd_agents_delete(args: argparse.Namespace, *, runtime: AgentCommandRuntime) -> None:
|
|
272
385
|
delete_associated_tables = bool(getattr(args, "delete_associated_tables", False))
|
|
273
386
|
if delete_associated_tables and not bool(getattr(args, "yes", False)):
|
|
@@ -465,6 +578,7 @@ def register_agents_subcommands(
|
|
|
465
578
|
# -- get --
|
|
466
579
|
pag = agents_sub.add_parser("get", help="Get one agent by id")
|
|
467
580
|
pag.add_argument("agent_id", help="Agent ID")
|
|
581
|
+
pag.add_argument("--out-file", dest="out_file", help="Write editable agent config JSON to file")
|
|
468
582
|
add_api_common_arguments(pag)
|
|
469
583
|
pag.set_defaults(func=handlers["get"])
|
|
470
584
|
|
|
@@ -577,9 +691,17 @@ def register_agents_subcommands(
|
|
|
577
691
|
help="Active-hours window end (HH:MM) — used by hourly/every_6h/every_12h",
|
|
578
692
|
)
|
|
579
693
|
pau.add_argument("--from-file", dest="from_file", help="Path to JSON patch payload file")
|
|
694
|
+
pau.add_argument("--dry-run", action="store_true", help="Preview the patch and diff without applying it")
|
|
580
695
|
add_api_common_arguments(pau)
|
|
581
696
|
pau.set_defaults(func=handlers["update"])
|
|
582
697
|
|
|
698
|
+
# -- diff --
|
|
699
|
+
padiff = agents_sub.add_parser("diff", help="Preview changes from a JSON patch without applying them")
|
|
700
|
+
padiff.add_argument("agent_id", help="Agent ID")
|
|
701
|
+
padiff.add_argument("--from-file", dest="from_file", required=True, help="Path to JSON patch payload file")
|
|
702
|
+
add_api_common_arguments(padiff)
|
|
703
|
+
padiff.set_defaults(func=handlers["diff"])
|
|
704
|
+
|
|
583
705
|
# -- delete --
|
|
584
706
|
pad = agents_sub.add_parser("delete", help="Soft-delete an agent and detach its associated tables")
|
|
585
707
|
pad.add_argument("agent_id", help="Agent ID")
|
|
@@ -77,6 +77,71 @@ def _attach_sequence_enroll_hints(output: Dict[str, Any], payload: Dict[str, Any
|
|
|
77
77
|
return enriched
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
def _sequence_shape(sequence: Dict[str, Any]) -> Dict[str, Any]:
|
|
81
|
+
steps = sequence.get("steps") if isinstance(sequence.get("steps"), list) else []
|
|
82
|
+
flow_graph = sequence.get("flowGraph") if isinstance(sequence.get("flowGraph"), dict) else {}
|
|
83
|
+
nodes = flow_graph.get("nodes") if isinstance(flow_graph.get("nodes"), list) else []
|
|
84
|
+
edges = flow_graph.get("edges") if isinstance(flow_graph.get("edges"), list) else []
|
|
85
|
+
return {
|
|
86
|
+
"step_count": len(steps),
|
|
87
|
+
"step_kinds": [str((step or {}).get("kind") or "") for step in steps if isinstance(step, dict)],
|
|
88
|
+
"flow_graph_present": bool(flow_graph),
|
|
89
|
+
"flow_graph_node_count": len(nodes),
|
|
90
|
+
"flow_graph_edge_count": len(edges),
|
|
91
|
+
"has_branching": any(str((node or {}).get("kind") or "").lower() in {"condition", "branch"} for node in nodes if isinstance(node, dict)),
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _fetch_sequence_readback(
|
|
96
|
+
sequence_id: str,
|
|
97
|
+
args: argparse.Namespace,
|
|
98
|
+
*,
|
|
99
|
+
runtime: SequenceCommandRuntime,
|
|
100
|
+
token: Optional[str],
|
|
101
|
+
) -> Optional[Dict[str, Any]]:
|
|
102
|
+
if not sequence_id:
|
|
103
|
+
return None
|
|
104
|
+
data = runtime.request_api(
|
|
105
|
+
"GET",
|
|
106
|
+
f"/api/sequences/{sequence_id}",
|
|
107
|
+
base_url=args.base_url,
|
|
108
|
+
token=token,
|
|
109
|
+
use_x_api_key=args.use_x_api_key,
|
|
110
|
+
timeout=args.timeout,
|
|
111
|
+
verbose=args.verbose,
|
|
112
|
+
)
|
|
113
|
+
return data if isinstance(data, dict) else None
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _sequence_mutation_output(
|
|
117
|
+
mutation_result: Dict[str, Any],
|
|
118
|
+
args: argparse.Namespace,
|
|
119
|
+
*,
|
|
120
|
+
runtime: SequenceCommandRuntime,
|
|
121
|
+
token: Optional[str],
|
|
122
|
+
submitted_payload: Optional[Dict[str, Any]] = None,
|
|
123
|
+
sequence_id: Optional[str] = None,
|
|
124
|
+
) -> Dict[str, Any]:
|
|
125
|
+
output = dict(mutation_result)
|
|
126
|
+
submitted_shape = _sequence_shape(submitted_payload) if isinstance(submitted_payload, dict) else None
|
|
127
|
+
if submitted_shape:
|
|
128
|
+
output["submitted_shape"] = submitted_shape
|
|
129
|
+
readback_id = str(sequence_id or output.get("id") or output.get("sequenceId") or "").strip()
|
|
130
|
+
readback = _fetch_sequence_readback(readback_id, args, runtime=runtime, token=token)
|
|
131
|
+
if readback:
|
|
132
|
+
readback_shape = _sequence_shape(readback)
|
|
133
|
+
output["sequence"] = readback
|
|
134
|
+
output["verified_readback"] = True
|
|
135
|
+
output["readback_shape"] = readback_shape
|
|
136
|
+
if submitted_shape:
|
|
137
|
+
output["readback_shape_matches_submitted"] = readback_shape == submitted_shape
|
|
138
|
+
output["verification_hint"] = "This output includes the sequence as saved by the API; summarize this readback, not only the submitted payload."
|
|
139
|
+
else:
|
|
140
|
+
output["verified_readback"] = False
|
|
141
|
+
output["verification_hint"] = "Could not read back the saved sequence; verify with `autotouch sequences get --sequence-id <id>` before summarizing."
|
|
142
|
+
return output
|
|
143
|
+
|
|
144
|
+
|
|
80
145
|
def _sequence_mutation_params(args: argparse.Namespace) -> Optional[Dict[str, Any]]:
|
|
81
146
|
return sequence_mutation_params_impl(args)
|
|
82
147
|
|
|
@@ -181,6 +246,8 @@ def cmd_sequences_create(args: argparse.Namespace, *, runtime: SequenceCommandRu
|
|
|
181
246
|
timeout=args.timeout,
|
|
182
247
|
verbose=args.verbose,
|
|
183
248
|
)
|
|
249
|
+
if isinstance(data, dict):
|
|
250
|
+
data = _sequence_mutation_output(data, args, runtime=runtime, token=token, submitted_payload=payload)
|
|
184
251
|
runtime.print_json(data, args.compact)
|
|
185
252
|
|
|
186
253
|
|
|
@@ -230,6 +297,8 @@ def cmd_sequences_update(args: argparse.Namespace, *, runtime: SequenceCommandRu
|
|
|
230
297
|
)
|
|
231
298
|
raise AutotouchAPIError(message, status_code=exc.status_code, response_body=exc.response_body) from exc
|
|
232
299
|
raise
|
|
300
|
+
if isinstance(data, dict):
|
|
301
|
+
data = _sequence_mutation_output(data, args, runtime=runtime, token=token, submitted_payload=payload, sequence_id=args.sequence_id)
|
|
233
302
|
runtime.print_json(data, args.compact)
|
|
234
303
|
|
|
235
304
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Autotouch CLI Reference
|
|
2
2
|
|
|
3
|
-
Generated from the installed parser for `autotouch-cli` `0.2.
|
|
3
|
+
Generated from the installed parser for `autotouch-cli` `0.2.94`.
|
|
4
4
|
Manifest schema version: `2`.
|
|
5
5
|
|
|
6
6
|
## Output Modes
|
|
@@ -20,10 +20,10 @@ Scheduled agent management
|
|
|
20
20
|
- Auth: `varies_by_subcommand`
|
|
21
21
|
- Stability: `stable`
|
|
22
22
|
- Destructive: `no`
|
|
23
|
-
- Subcommands: `list, get, create, update, delete, run, runs, watch, generate-persona, generate-topics, generate-job-signal, signals`
|
|
23
|
+
- Subcommands: `list, get, create, update, diff, delete, run, runs, watch, generate-persona, generate-topics, generate-job-signal, signals`
|
|
24
24
|
- Example:
|
|
25
25
|
- `autotouch agents [-h]
|
|
26
|
-
{list,get,create,update,delete,run,runs,watch,generate-persona,generate-topics,generate-job-signal,signals} ...`
|
|
26
|
+
{list,get,create,update,diff,delete,run,runs,watch,generate-persona,generate-topics,generate-job-signal,signals} ...`
|
|
27
27
|
|
|
28
28
|
#### `autotouch agents create`
|
|
29
29
|
|
|
@@ -112,6 +112,35 @@ Soft-delete an agent and detach its associated tables
|
|
|
112
112
|
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
113
113
|
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
114
114
|
|
|
115
|
+
#### `autotouch agents diff`
|
|
116
|
+
|
|
117
|
+
Preview changes from a JSON patch without applying them
|
|
118
|
+
|
|
119
|
+
- Auth: `developer_key_or_user_session`
|
|
120
|
+
- Stability: `stable`
|
|
121
|
+
- Destructive: `no`
|
|
122
|
+
- Required flags: `--from-file`
|
|
123
|
+
- Output modes: `json, ndjson, human`
|
|
124
|
+
- Example:
|
|
125
|
+
- `autotouch agents diff [-h] --from-file FROM_FILE [--base-url BASE_URL]
|
|
126
|
+
[--token TOKEN] [--use-x-api-key]
|
|
127
|
+
[--timeout TIMEOUT]
|
|
128
|
+
[--output {json,ndjson,human}] [--compact]
|
|
129
|
+
[--select SELECT | --json-pointer JSON_POINTER]
|
|
130
|
+
[--verbose]
|
|
131
|
+
agent_id`
|
|
132
|
+
- Options:
|
|
133
|
+
- `--from-file` (required; kind=file; input=file): Path to JSON patch payload file
|
|
134
|
+
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
135
|
+
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
136
|
+
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
137
|
+
- `--timeout` (kind=integer; default=30): HTTP timeout in seconds
|
|
138
|
+
- `--output` (kind=string; choices=json,ndjson,human; default=json): Output mode
|
|
139
|
+
- `--compact` (kind=boolean; when omitted=False; when present=True): Print compact JSON
|
|
140
|
+
- `--select` (kind=string): Extract a dotted field path from the final result (for example: id or items.0.id)
|
|
141
|
+
- `--json-pointer` (kind=string): Extract a JSON pointer from the final result (for example: /id)
|
|
142
|
+
- `--verbose` (kind=boolean; when omitted=False; when present=True): Print request metadata to stderr
|
|
143
|
+
|
|
115
144
|
#### `autotouch agents generate-job-signal`
|
|
116
145
|
|
|
117
146
|
Generate job signal config via AI
|
|
@@ -218,13 +247,14 @@ Get one agent by id
|
|
|
218
247
|
- Destructive: `no`
|
|
219
248
|
- Output modes: `json, ndjson, human`
|
|
220
249
|
- Example:
|
|
221
|
-
- `autotouch agents get [-h] [--
|
|
222
|
-
[--use-x-api-key]
|
|
223
|
-
[--output {json,ndjson,human}]
|
|
224
|
-
[--select SELECT |
|
|
225
|
-
[--verbose]
|
|
250
|
+
- `autotouch agents get [-h] [--out-file OUT_FILE] [--base-url BASE_URL]
|
|
251
|
+
[--token TOKEN] [--use-x-api-key]
|
|
252
|
+
[--timeout TIMEOUT] [--output {json,ndjson,human}]
|
|
253
|
+
[--compact] [--select SELECT |
|
|
254
|
+
--json-pointer JSON_POINTER] [--verbose]
|
|
226
255
|
agent_id`
|
|
227
256
|
- Options:
|
|
257
|
+
- `--out-file` (kind=file; input=file): Write editable agent config JSON to file
|
|
228
258
|
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
229
259
|
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
230
260
|
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
@@ -362,9 +392,9 @@ Update an existing agent
|
|
|
362
392
|
[--schedule-day-of-week 0-6]
|
|
363
393
|
[--schedule-window-start SCHEDULE_WINDOW_START]
|
|
364
394
|
[--schedule-window-end SCHEDULE_WINDOW_END]
|
|
365
|
-
[--from-file FROM_FILE] [--
|
|
366
|
-
[--
|
|
367
|
-
[--timeout TIMEOUT]
|
|
395
|
+
[--from-file FROM_FILE] [--dry-run]
|
|
396
|
+
[--base-url BASE_URL] [--token TOKEN]
|
|
397
|
+
[--use-x-api-key] [--timeout TIMEOUT]
|
|
368
398
|
[--output {json,ndjson,human}] [--compact]
|
|
369
399
|
[--select SELECT | --json-pointer JSON_POINTER]
|
|
370
400
|
[--verbose]
|
|
@@ -385,6 +415,7 @@ Update an existing agent
|
|
|
385
415
|
- `--schedule-window-start` (kind=string): Active-hours window start (HH:MM) — used by hourly/every_6h/every_12h
|
|
386
416
|
- `--schedule-window-end` (kind=string): Active-hours window end (HH:MM) — used by hourly/every_6h/every_12h
|
|
387
417
|
- `--from-file` (kind=file; input=file): Path to JSON patch payload file
|
|
418
|
+
- `--dry-run` (kind=boolean; when omitted=False; when present=True): Preview the patch and diff without applying it
|
|
388
419
|
- `--base-url` (kind=string; default=https://app.autotouch.ai): API base URL (default: https://app.autotouch.ai)
|
|
389
420
|
- `--token` (kind=string; sensitive): Developer API key / JWT token
|
|
390
421
|
- `--use-x-api-key` (kind=boolean; when omitted=False; when present=True): Send token via X-API-Key header
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.2.
|
|
2
|
+
"version": "0.2.94",
|
|
3
3
|
"manifest_schema_version": 2,
|
|
4
4
|
"entry_points": {
|
|
5
5
|
"autotouch": "autotouch_cli.cli:main",
|
|
@@ -34390,6 +34390,7 @@
|
|
|
34390
34390
|
"get",
|
|
34391
34391
|
"create",
|
|
34392
34392
|
"update",
|
|
34393
|
+
"diff",
|
|
34393
34394
|
"delete",
|
|
34394
34395
|
"run",
|
|
34395
34396
|
"runs",
|
|
@@ -34405,7 +34406,7 @@
|
|
|
34405
34406
|
"output_contract": null,
|
|
34406
34407
|
"availability": null,
|
|
34407
34408
|
"examples": [
|
|
34408
|
-
"autotouch agents [-h]\n {list,get,create,update,delete,run,runs,watch,generate-persona,generate-topics,generate-job-signal,signals} ..."
|
|
34409
|
+
"autotouch agents [-h]\n {list,get,create,update,diff,delete,run,runs,watch,generate-persona,generate-topics,generate-job-signal,signals} ..."
|
|
34409
34410
|
],
|
|
34410
34411
|
"stability": "stable",
|
|
34411
34412
|
"handler": null
|
|
@@ -34606,6 +34607,18 @@
|
|
|
34606
34607
|
}
|
|
34607
34608
|
],
|
|
34608
34609
|
"options": [
|
|
34610
|
+
{
|
|
34611
|
+
"dest": "out_file",
|
|
34612
|
+
"required": false,
|
|
34613
|
+
"help": "Write editable agent config JSON to file",
|
|
34614
|
+
"kind": "file",
|
|
34615
|
+
"action": "store",
|
|
34616
|
+
"input_kind": "file",
|
|
34617
|
+
"flags": [
|
|
34618
|
+
"--out-file"
|
|
34619
|
+
],
|
|
34620
|
+
"takes_value": true
|
|
34621
|
+
},
|
|
34609
34622
|
{
|
|
34610
34623
|
"dest": "base_url",
|
|
34611
34624
|
"required": false,
|
|
@@ -34759,7 +34772,7 @@
|
|
|
34759
34772
|
},
|
|
34760
34773
|
"availability": null,
|
|
34761
34774
|
"examples": [
|
|
34762
|
-
"autotouch agents get [-h] [--base-url BASE_URL]
|
|
34775
|
+
"autotouch agents get [-h] [--out-file OUT_FILE] [--base-url BASE_URL]\n [--token TOKEN] [--use-x-api-key]\n [--timeout TIMEOUT] [--output {json,ndjson,human}]\n [--compact] [--select SELECT |\n --json-pointer JSON_POINTER] [--verbose]\n agent_id"
|
|
34763
34776
|
],
|
|
34764
34777
|
"stability": "stable",
|
|
34765
34778
|
"handler": "_fn"
|
|
@@ -35403,6 +35416,216 @@
|
|
|
35403
35416
|
],
|
|
35404
35417
|
"takes_value": true
|
|
35405
35418
|
},
|
|
35419
|
+
{
|
|
35420
|
+
"dest": "dry_run",
|
|
35421
|
+
"required": false,
|
|
35422
|
+
"help": "Preview the patch and diff without applying it",
|
|
35423
|
+
"kind": "boolean",
|
|
35424
|
+
"action": "store_true",
|
|
35425
|
+
"nargs": 0,
|
|
35426
|
+
"default_when_omitted": false,
|
|
35427
|
+
"value_when_present": true,
|
|
35428
|
+
"flags": [
|
|
35429
|
+
"--dry-run"
|
|
35430
|
+
],
|
|
35431
|
+
"takes_value": false
|
|
35432
|
+
},
|
|
35433
|
+
{
|
|
35434
|
+
"dest": "base_url",
|
|
35435
|
+
"required": false,
|
|
35436
|
+
"help": "API base URL (default: https://app.autotouch.ai)",
|
|
35437
|
+
"kind": "string",
|
|
35438
|
+
"action": "store",
|
|
35439
|
+
"default_when_omitted": "https://app.autotouch.ai",
|
|
35440
|
+
"default": "https://app.autotouch.ai",
|
|
35441
|
+
"flags": [
|
|
35442
|
+
"--base-url"
|
|
35443
|
+
],
|
|
35444
|
+
"takes_value": true
|
|
35445
|
+
},
|
|
35446
|
+
{
|
|
35447
|
+
"dest": "token",
|
|
35448
|
+
"required": false,
|
|
35449
|
+
"help": "Developer API key / JWT token",
|
|
35450
|
+
"kind": "string",
|
|
35451
|
+
"action": "store",
|
|
35452
|
+
"sensitive": true,
|
|
35453
|
+
"flags": [
|
|
35454
|
+
"--token"
|
|
35455
|
+
],
|
|
35456
|
+
"takes_value": true
|
|
35457
|
+
},
|
|
35458
|
+
{
|
|
35459
|
+
"dest": "use_x_api_key",
|
|
35460
|
+
"required": false,
|
|
35461
|
+
"help": "Send token via X-API-Key header",
|
|
35462
|
+
"kind": "boolean",
|
|
35463
|
+
"action": "store_true",
|
|
35464
|
+
"nargs": 0,
|
|
35465
|
+
"default_when_omitted": false,
|
|
35466
|
+
"value_when_present": true,
|
|
35467
|
+
"flags": [
|
|
35468
|
+
"--use-x-api-key"
|
|
35469
|
+
],
|
|
35470
|
+
"takes_value": false
|
|
35471
|
+
},
|
|
35472
|
+
{
|
|
35473
|
+
"dest": "timeout",
|
|
35474
|
+
"required": false,
|
|
35475
|
+
"help": "HTTP timeout in seconds",
|
|
35476
|
+
"kind": "integer",
|
|
35477
|
+
"action": "store",
|
|
35478
|
+
"default_when_omitted": 30,
|
|
35479
|
+
"default": 30,
|
|
35480
|
+
"flags": [
|
|
35481
|
+
"--timeout"
|
|
35482
|
+
],
|
|
35483
|
+
"takes_value": true
|
|
35484
|
+
},
|
|
35485
|
+
{
|
|
35486
|
+
"dest": "output",
|
|
35487
|
+
"required": false,
|
|
35488
|
+
"help": "Output mode",
|
|
35489
|
+
"kind": "string",
|
|
35490
|
+
"action": "store",
|
|
35491
|
+
"choices": [
|
|
35492
|
+
"json",
|
|
35493
|
+
"ndjson",
|
|
35494
|
+
"human"
|
|
35495
|
+
],
|
|
35496
|
+
"default_when_omitted": "json",
|
|
35497
|
+
"default": "json",
|
|
35498
|
+
"flags": [
|
|
35499
|
+
"--output"
|
|
35500
|
+
],
|
|
35501
|
+
"takes_value": true
|
|
35502
|
+
},
|
|
35503
|
+
{
|
|
35504
|
+
"dest": "compact",
|
|
35505
|
+
"required": false,
|
|
35506
|
+
"help": "Print compact JSON",
|
|
35507
|
+
"kind": "boolean",
|
|
35508
|
+
"action": "store_true",
|
|
35509
|
+
"nargs": 0,
|
|
35510
|
+
"default_when_omitted": false,
|
|
35511
|
+
"value_when_present": true,
|
|
35512
|
+
"flags": [
|
|
35513
|
+
"--compact"
|
|
35514
|
+
],
|
|
35515
|
+
"takes_value": false
|
|
35516
|
+
},
|
|
35517
|
+
{
|
|
35518
|
+
"dest": "select",
|
|
35519
|
+
"required": false,
|
|
35520
|
+
"help": "Extract a dotted field path from the final result (for example: id or items.0.id)",
|
|
35521
|
+
"kind": "string",
|
|
35522
|
+
"action": "store",
|
|
35523
|
+
"flags": [
|
|
35524
|
+
"--select"
|
|
35525
|
+
],
|
|
35526
|
+
"takes_value": true
|
|
35527
|
+
},
|
|
35528
|
+
{
|
|
35529
|
+
"dest": "json_pointer",
|
|
35530
|
+
"required": false,
|
|
35531
|
+
"help": "Extract a JSON pointer from the final result (for example: /id)",
|
|
35532
|
+
"kind": "string",
|
|
35533
|
+
"action": "store",
|
|
35534
|
+
"flags": [
|
|
35535
|
+
"--json-pointer"
|
|
35536
|
+
],
|
|
35537
|
+
"takes_value": true
|
|
35538
|
+
},
|
|
35539
|
+
{
|
|
35540
|
+
"dest": "verbose",
|
|
35541
|
+
"required": false,
|
|
35542
|
+
"help": "Print request metadata to stderr",
|
|
35543
|
+
"kind": "boolean",
|
|
35544
|
+
"action": "store_true",
|
|
35545
|
+
"nargs": 0,
|
|
35546
|
+
"default_when_omitted": false,
|
|
35547
|
+
"value_when_present": true,
|
|
35548
|
+
"flags": [
|
|
35549
|
+
"--verbose"
|
|
35550
|
+
],
|
|
35551
|
+
"takes_value": false
|
|
35552
|
+
}
|
|
35553
|
+
],
|
|
35554
|
+
"mutually_exclusive_groups": [
|
|
35555
|
+
{
|
|
35556
|
+
"required": false,
|
|
35557
|
+
"options": [
|
|
35558
|
+
"--select",
|
|
35559
|
+
"--json-pointer"
|
|
35560
|
+
]
|
|
35561
|
+
}
|
|
35562
|
+
],
|
|
35563
|
+
"subcommands": [],
|
|
35564
|
+
"leaf_command": true,
|
|
35565
|
+
"auth_mode": "developer_key_or_user_session",
|
|
35566
|
+
"destructive": false,
|
|
35567
|
+
"output_contract": {
|
|
35568
|
+
"modes": [
|
|
35569
|
+
"json",
|
|
35570
|
+
"ndjson",
|
|
35571
|
+
"human"
|
|
35572
|
+
],
|
|
35573
|
+
"json": {
|
|
35574
|
+
"single_document": true
|
|
35575
|
+
},
|
|
35576
|
+
"ndjson": {
|
|
35577
|
+
"streaming": true,
|
|
35578
|
+
"recommended_for": "progress updates / watch flows"
|
|
35579
|
+
},
|
|
35580
|
+
"human": {
|
|
35581
|
+
"interactive": true
|
|
35582
|
+
}
|
|
35583
|
+
},
|
|
35584
|
+
"availability": null,
|
|
35585
|
+
"examples": [
|
|
35586
|
+
"autotouch agents update [-h] [--name NAME]\n [--status {DRAFT,ACTIVE,PAUSED}]\n [--auto-find-email AUTO_FIND_EMAIL]\n [--auto-find-phone AUTO_FIND_PHONE]\n [--auto-broaden AUTO_BROADEN]\n [--auto-create-lead-mode {qualified_only,everyone,manual_only}]\n [--auto-sequence-id AUTO_SEQUENCE_ID]\n [--schedule-time SCHEDULE_TIME]\n [--schedule-tz SCHEDULE_TZ]\n [--schedule-frequency {hourly,every_6h,every_12h,daily,weekly}]\n [--schedule-days {all,weekdays}]\n [--schedule-day-of-week 0-6]\n [--schedule-window-start SCHEDULE_WINDOW_START]\n [--schedule-window-end SCHEDULE_WINDOW_END]\n [--from-file FROM_FILE] [--dry-run]\n [--base-url BASE_URL] [--token TOKEN]\n [--use-x-api-key] [--timeout TIMEOUT]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT | --json-pointer JSON_POINTER]\n [--verbose]\n agent_id"
|
|
35587
|
+
],
|
|
35588
|
+
"stability": "stable",
|
|
35589
|
+
"handler": "_fn"
|
|
35590
|
+
},
|
|
35591
|
+
"agents.diff": {
|
|
35592
|
+
"canonical": [
|
|
35593
|
+
"autotouch",
|
|
35594
|
+
"agents",
|
|
35595
|
+
"diff"
|
|
35596
|
+
],
|
|
35597
|
+
"aliases": [],
|
|
35598
|
+
"group": "agents",
|
|
35599
|
+
"help": "Preview changes from a JSON patch without applying them",
|
|
35600
|
+
"description": null,
|
|
35601
|
+
"notes": null,
|
|
35602
|
+
"required_flags": [
|
|
35603
|
+
"--from-file"
|
|
35604
|
+
],
|
|
35605
|
+
"positionals": [
|
|
35606
|
+
{
|
|
35607
|
+
"dest": "agent_id",
|
|
35608
|
+
"required": true,
|
|
35609
|
+
"help": "Agent ID",
|
|
35610
|
+
"kind": "string",
|
|
35611
|
+
"action": "store",
|
|
35612
|
+
"name": "agent_id",
|
|
35613
|
+
"positional": true
|
|
35614
|
+
}
|
|
35615
|
+
],
|
|
35616
|
+
"options": [
|
|
35617
|
+
{
|
|
35618
|
+
"dest": "from_file",
|
|
35619
|
+
"required": true,
|
|
35620
|
+
"help": "Path to JSON patch payload file",
|
|
35621
|
+
"kind": "file",
|
|
35622
|
+
"action": "store",
|
|
35623
|
+
"input_kind": "file",
|
|
35624
|
+
"flags": [
|
|
35625
|
+
"--from-file"
|
|
35626
|
+
],
|
|
35627
|
+
"takes_value": true
|
|
35628
|
+
},
|
|
35406
35629
|
{
|
|
35407
35630
|
"dest": "base_url",
|
|
35408
35631
|
"required": false,
|
|
@@ -35556,7 +35779,7 @@
|
|
|
35556
35779
|
},
|
|
35557
35780
|
"availability": null,
|
|
35558
35781
|
"examples": [
|
|
35559
|
-
"autotouch agents
|
|
35782
|
+
"autotouch agents diff [-h] --from-file FROM_FILE [--base-url BASE_URL]\n [--token TOKEN] [--use-x-api-key]\n [--timeout TIMEOUT]\n [--output {json,ndjson,human}] [--compact]\n [--select SELECT | --json-pointer JSON_POINTER]\n [--verbose]\n agent_id"
|
|
35560
35783
|
],
|
|
35561
35784
|
"stability": "stable",
|
|
35562
35785
|
"handler": "_fn"
|
|
@@ -782,6 +782,7 @@ def build_parser(
|
|
|
782
782
|
"get": commands["agents_get"],
|
|
783
783
|
"create": commands["agents_create"],
|
|
784
784
|
"update": commands["agents_update"],
|
|
785
|
+
"diff": commands["agents_diff"],
|
|
785
786
|
"delete": commands["agents_delete"],
|
|
786
787
|
"run": commands["agents_run"],
|
|
787
788
|
"runs": commands["agents_runs"],
|
|
@@ -379,10 +379,10 @@ SEQUENCE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
|
379
379
|
{
|
|
380
380
|
"id": "connect_1",
|
|
381
381
|
"kind": "LINKEDIN_CONNECT",
|
|
382
|
-
"waitDays":
|
|
382
|
+
"waitDays": 0,
|
|
383
383
|
"waitHours": 0,
|
|
384
|
-
"waitMinutes":
|
|
385
|
-
"executionMode": "
|
|
384
|
+
"waitMinutes": 7,
|
|
385
|
+
"executionMode": "MANUAL",
|
|
386
386
|
"aiDraft": True,
|
|
387
387
|
"scriptTemplate": "",
|
|
388
388
|
},
|
|
@@ -392,8 +392,8 @@ SEQUENCE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
|
392
392
|
"waitDays": 0,
|
|
393
393
|
"waitHours": 0,
|
|
394
394
|
"waitMinutes": 0,
|
|
395
|
-
"executionMode": "
|
|
396
|
-
"emailSendMode": "
|
|
395
|
+
"executionMode": "MANUAL",
|
|
396
|
+
"emailSendMode": "MANUAL",
|
|
397
397
|
"emailIsReply": False,
|
|
398
398
|
"appendSignature": True,
|
|
399
399
|
"aiDraft": True,
|
|
@@ -406,7 +406,7 @@ SEQUENCE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
|
406
406
|
"waitDays": 0,
|
|
407
407
|
"waitHours": 0,
|
|
408
408
|
"waitMinutes": 0,
|
|
409
|
-
"executionMode": "
|
|
409
|
+
"executionMode": "MANUAL",
|
|
410
410
|
"aiDraft": True,
|
|
411
411
|
"scriptTemplate": "",
|
|
412
412
|
},
|
|
@@ -527,28 +527,29 @@ SEQUENCE_RECIPES: Dict[str, Dict[str, Any]] = {
|
|
|
527
527
|
|
|
528
528
|
SEQUENCE_RECIPE_NOTES: Dict[str, List[str]] = {
|
|
529
529
|
"create": [
|
|
530
|
-
"Recommended default:
|
|
531
|
-
"
|
|
530
|
+
"Recommended default: branch-aware sequence payload with personal delivery plus AUTOMATED email with aiDraft=true.",
|
|
531
|
+
"Keep steps aligned with graph action sourceStepId values.",
|
|
532
532
|
"AI draft generates subject + body at execution time.",
|
|
533
533
|
"AI draft for call generates a call script.",
|
|
534
534
|
"External sequence create/update requires sourceTableId.",
|
|
535
535
|
"Pass --actor-user-id on mutating commands when you need explicit actor resolution.",
|
|
536
536
|
],
|
|
537
537
|
"bulk_automated": [
|
|
538
|
-
"Emits a
|
|
538
|
+
"Emits a branch-aware sequence payload with two automated email actions.",
|
|
539
539
|
"Use this when the provider should send email automatically at scale.",
|
|
540
540
|
"Bulk delivery sequences cannot contain MANUAL email steps, so aiDraft does not apply to those email steps.",
|
|
541
541
|
"Activate only after provider readiness is configured (autotouch sequences delivery-status).",
|
|
542
542
|
],
|
|
543
543
|
"linkedin_outreach": [
|
|
544
|
-
"Emits
|
|
544
|
+
"Emits the standard LinkedIn branch sequence: visit profile, manual AI-drafted connect, wait for accepted connection, then branch to LinkedIn message or email.",
|
|
545
545
|
"Supported step kinds: LINKEDIN_VISIT_PROFILE, LINKEDIN_CONNECT, LINKEDIN_CHAT_MESSAGE, LINKEDIN_VOICE_MESSAGE.",
|
|
546
546
|
"LINKEDIN_VISIT_PROFILE is always AUTOMATED and visits the lead's profile (notifies by default).",
|
|
547
|
-
"
|
|
548
|
-
"
|
|
547
|
+
"For manual AI-drafted LinkedIn steps, set executionMode=MANUAL, aiDraft=true, and scriptTemplate=\"\".",
|
|
548
|
+
"LINKEDIN_CONNECT drafts a connection request; invite notes must stay under 300 chars.",
|
|
549
|
+
"LINKEDIN_CHAT_MESSAGE creates a direct-message task after connection is accepted.",
|
|
549
550
|
"LINKEDIN_VOICE_MESSAGE sends a voice note; only works for 1st degree connections.",
|
|
550
551
|
"Connection degree (1st/2nd/3rd/out_of_network) is auto-detected from the LinkedIn profile.",
|
|
551
|
-
"
|
|
552
|
+
"Every branch must be explicit and must route to the action that should run on that path.",
|
|
552
553
|
"Set stopOnLinkedInReply=true in exitRules to stop the sequence when the lead replies on LinkedIn.",
|
|
553
554
|
"Leads must have a linkedin_url field to be reachable for LinkedIn steps.",
|
|
554
555
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autotouch-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.94
|
|
4
4
|
Summary: Autotouch Smart Table CLI
|
|
5
5
|
Project-URL: Homepage, https://app.autotouch.ai
|
|
6
6
|
Project-URL: Documentation, https://github.com/nicolonic/autotouch_main/tree/main/docs/research-table/reference
|
|
@@ -178,7 +178,7 @@ For automation or agent-driven setup, use:
|
|
|
178
178
|
- `autotouch cli-manifest --output json` for the local machine-readable command contract
|
|
179
179
|
- `autotouch cli-reference` for the shipped parser-generated reference
|
|
180
180
|
- `autotouch capabilities --output json` for provider/workflow contracts
|
|
181
|
-
- `autotouch --version` should be `0.2.
|
|
181
|
+
- `autotouch --version` should be `0.2.94` or newer for structured company list builds without user-supplied keywords, stored list-build input lookup, research-workspace list-build guidance, the cleaned single LinkedIn-sourced list-build path, Exa Company Search up to 100 results, scheduled agent `--target ACCOUNTS|LEADS`, paced HTTP Request column contracts, branch-aware LinkedIn sequence recipes, real agent soft-delete with associated-table handling, and research-table sequence handoff assignee config
|
|
182
182
|
- `autotouch capabilities --output json --select list_builds` for documented list-build inputs such as geography IDs, company size buckets, profile language, and company IDs
|
|
183
183
|
- `autotouch list-build inputs` and `autotouch list-build pricing` before creating durable list-build jobs
|
|
184
184
|
- `autotouch list-build companies` and `autotouch list-build leads` for durable LinkedIn-sourced company and lead list builds with Smart Table-owned background workers, visible progress, and no user-owned LinkedIn connection requirement
|
|
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
|
|
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
|
|
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
|