autotouch-cli 0.2.47__tar.gz → 0.2.48__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 (46) hide show
  1. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/PKG-INFO +14 -5
  2. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/README.md +13 -4
  3. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/data/CLI_REFERENCE.md +1 -1
  4. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/data/cli-manifest.json +1 -1
  5. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/PKG-INFO +14 -5
  6. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_shared/provider_registry.py +97 -7
  7. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/pyproject.toml +1 -1
  8. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/MANIFEST.in +0 -0
  9. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/__init__.py +0 -0
  10. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/cli.py +0 -0
  11. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/cli_contracts.py +0 -0
  12. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/__init__.py +0 -0
  13. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/auth.py +0 -0
  14. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/cells.py +0 -0
  15. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/columns.py +0 -0
  16. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/jobs.py +0 -0
  17. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/leads.py +0 -0
  18. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/linkedin.py +0 -0
  19. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/prompts.py +0 -0
  20. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/rows.py +0 -0
  21. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/search.py +0 -0
  22. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/sequences.py +0 -0
  23. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/tables.py +0 -0
  24. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/tasks.py +0 -0
  25. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/webhooks.py +0 -0
  26. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/commands/workspace_secrets.py +0 -0
  27. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/__init__.py +0 -0
  28. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/auth.py +0 -0
  29. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/config.py +0 -0
  30. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/http.py +0 -0
  31. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/io.py +0 -0
  32. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/output.py +0 -0
  33. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/core/polling.py +0 -0
  34. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/mongo_status.py +0 -0
  35. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/parser_groups.py +0 -0
  36. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/sequence_support.py +0 -0
  37. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli/templates.py +0 -0
  38. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/SOURCES.txt +0 -0
  39. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/dependency_links.txt +0 -0
  40. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/entry_points.txt +0 -0
  41. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/requires.txt +0 -0
  42. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_cli.egg-info/top_level.txt +0 -0
  43. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_shared/__init__.py +0 -0
  44. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_shared/linkedin_contract.py +0 -0
  45. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/autotouch_shared/search_contract.py +0 -0
  46. {autotouch_cli-0.2.47 → autotouch_cli-0.2.48}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.47
3
+ Version: 0.2.48
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
@@ -146,9 +146,18 @@ For automation or agent-driven setup, use:
146
146
  - `autotouch sequences ...` and `autotouch tasks ...` for sequence/task workflows
147
147
  - `pip install 'autotouch-cli[mongo]'` if you need the Mongo-backed `status` / `watch` commands
148
148
 
149
+ ## LLM Columns
150
+
151
+ For `llm_enrichment` in `agent` mode, the recommended path is:
152
+ - provide `config.instructions`
153
+ - let the API compile the runnable prompt
154
+ - keep `config.useAutoSchema = true`
155
+
156
+ Only send `user_schema` / `response_schema` when you intentionally want to override the generated schema and keep it aligned yourself. The installed recipe surface at `autotouch columns recipe --type llm_enrichment` follows this contract.
157
+
149
158
  ## Docs
150
159
 
151
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/autotouch-cli.md
152
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/guides/autotouch-cli-agent-playbook.md
153
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/tables-api.md
154
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/platform/authentication.md
160
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
161
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
163
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
@@ -121,9 +121,18 @@ For automation or agent-driven setup, use:
121
121
  - `autotouch sequences ...` and `autotouch tasks ...` for sequence/task workflows
122
122
  - `pip install 'autotouch-cli[mongo]'` if you need the Mongo-backed `status` / `watch` commands
123
123
 
124
+ ## LLM Columns
125
+
126
+ For `llm_enrichment` in `agent` mode, the recommended path is:
127
+ - provide `config.instructions`
128
+ - let the API compile the runnable prompt
129
+ - keep `config.useAutoSchema = true`
130
+
131
+ Only send `user_schema` / `response_schema` when you intentionally want to override the generated schema and keep it aligned yourself. The installed recipe surface at `autotouch columns recipe --type llm_enrichment` follows this contract.
132
+
124
133
  ## Docs
125
134
 
126
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/autotouch-cli.md
127
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/guides/autotouch-cli-agent-playbook.md
128
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/tables-api.md
129
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/platform/authentication.md
135
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
136
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
137
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
138
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
@@ -1,6 +1,6 @@
1
1
  # Autotouch CLI Reference
2
2
 
3
- Generated from the installed parser for `autotouch-cli` `0.2.47`.
3
+ Generated from the installed parser for `autotouch-cli` `0.2.48`.
4
4
  Manifest schema version: `2`.
5
5
 
6
6
  ## Output Modes
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.47",
2
+ "version": "0.2.48",
3
3
  "manifest_schema_version": 2,
4
4
  "entry_points": {
5
5
  "autotouch": "autotouch_cli.cli:main",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: autotouch-cli
3
- Version: 0.2.47
3
+ Version: 0.2.48
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
@@ -146,9 +146,18 @@ For automation or agent-driven setup, use:
146
146
  - `autotouch sequences ...` and `autotouch tasks ...` for sequence/task workflows
147
147
  - `pip install 'autotouch-cli[mongo]'` if you need the Mongo-backed `status` / `watch` commands
148
148
 
149
+ ## LLM Columns
150
+
151
+ For `llm_enrichment` in `agent` mode, the recommended path is:
152
+ - provide `config.instructions`
153
+ - let the API compile the runnable prompt
154
+ - keep `config.useAutoSchema = true`
155
+
156
+ Only send `user_schema` / `response_schema` when you intentionally want to override the generated schema and keep it aligned yourself. The installed recipe surface at `autotouch columns recipe --type llm_enrichment` follows this contract.
157
+
149
158
  ## Docs
150
159
 
151
- - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/autotouch-cli.md
152
- - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/guides/autotouch-cli-agent-playbook.md
153
- - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/research-table/reference/tables-api.md
154
- - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.47/docs/platform/authentication.md
160
+ - Full CLI reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/autotouch-cli.md
161
+ - Agent playbook: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/guides/autotouch-cli-agent-playbook.md
162
+ - Tables/API reference: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/research-table/reference/tables-api.md
163
+ - Authentication/scopes: https://github.com/nicolonic/autotouch_main/blob/autotouch-cli-v0.2.48/docs/platform/authentication.md
@@ -30,6 +30,7 @@ class ResearchTableProviderContract:
30
30
  key: str
31
31
  display_name: str
32
32
  kind: str
33
+ behavior_class: str = "standard_enrichment"
33
34
  provider_aliases: Tuple[str, ...] = ()
34
35
  origin_aliases: Tuple[str, ...] = ()
35
36
  recipe_type: Optional[str] = None
@@ -39,6 +40,7 @@ class ResearchTableProviderContract:
39
40
  setup_contract: Dict[str, Any] = field(default_factory=dict)
40
41
  execution_policy: Optional[AutoRunExecutionPolicy] = None
41
42
  dispatch_strategy: str = "bulk_queue"
43
+ readiness_strategy: Optional[str] = None
42
44
  save_time_entrypoint: Optional[str] = None
43
45
  is_action_provider: bool = False
44
46
  composition_contract: Dict[str, Any] = field(default_factory=dict)
@@ -72,10 +74,12 @@ class ResearchTableProviderContract:
72
74
  payload: Dict[str, Any] = {
73
75
  "display_name": self.display_name,
74
76
  "kind": self.kind,
77
+ "behavior_class": self.behavior_class,
75
78
  "recipe_type": self.recipe_type,
76
79
  "provider_aliases": list(self.provider_aliases or ()),
77
80
  "origin_aliases": list(self.origin_aliases or ()),
78
81
  "dispatch_strategy": self.dispatch_strategy,
82
+ "readiness_strategy": self.readiness_strategy,
79
83
  "action_provider": bool(self.is_action_provider),
80
84
  "setup_contract": deepcopy(self.setup_contract),
81
85
  "composition_contract": deepcopy(self.composition_contract),
@@ -271,6 +275,7 @@ _ADD_TO_SEQUENCE_POLICY = AutoRunExecutionPolicy(
271
275
  force_rerun=False,
272
276
  respect_existing_done=True,
273
277
  default_batch_size=50,
278
+ batch_size_env="ADD_TO_SEQUENCE_BATCH_SIZE",
274
279
  )
275
280
 
276
281
  _HTTP_REQUEST_POLICY = AutoRunExecutionPolicy(
@@ -293,6 +298,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
293
298
  key="formatter",
294
299
  display_name="Formatter",
295
300
  kind="formatter",
301
+ behavior_class="formatter",
296
302
  recipe_type="formatter",
297
303
  recipe_payload={
298
304
  "key": "engagement_statement",
@@ -343,6 +349,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
343
349
  key="llm",
344
350
  display_name="LLM Enrichment",
345
351
  kind="enrichment",
352
+ behavior_class="standard_enrichment",
346
353
  provider_aliases=_llm_provider_values(),
347
354
  recipe_type="llm_enrichment",
348
355
  recipe_payload={
@@ -365,8 +372,10 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
365
372
  },
366
373
  recipe_notes=(
367
374
  "Recommended default for agent mode: provide instructions and let the API compile the runnable prompt.",
375
+ "When the platform generates the runnable prompt from instructions, keep useAutoSchema=true unless you intentionally want to own the schema yourself.",
376
+ "Do not send user_schema/response_schema in that default generated-prompt path; prompt/schema drift is possible if you later change the generated prompt but keep a frozen custom schema.",
368
377
  "Basic is for extraction, scoring, or classification using fields already in the row. Agent is for tasks that may need outside lookup or web research.",
369
- "Create/update always materializes the runnable prompt into config.prompt/advancedPrompt before execution.",
378
+ "Create/update always materializes the runnable prompt into config.advancedPrompt before execution.",
370
379
  "Generated agent-mode prompts always include company/requester context.",
371
380
  "Basic mode stays manual-prompt-first; write the prompt directly from the user goal/preferences.",
372
381
  "Runtime only injects values for placeholders the prompt explicitly references.",
@@ -431,10 +440,10 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
431
440
  "generated": {
432
441
  "instructions_field": "config.instructions",
433
442
  "prompt_source": "generated",
434
- "materialized_prompt_fields": ["config.prompt", "config.advancedPrompt"],
443
+ "materialized_prompt_fields": ["config.advancedPrompt"],
435
444
  },
436
445
  "manual": {
437
- "prompt_field": "config.prompt",
446
+ "prompt_field": "config.advancedPrompt",
438
447
  "prompt_source": "manual",
439
448
  },
440
449
  },
@@ -477,13 +486,14 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
477
486
  ],
478
487
  },
479
488
  execution_policy=_LLM_POLICY,
480
- dispatch_strategy="llm_scheduler",
489
+ dispatch_strategy="bulk_queue",
481
490
  save_time_entrypoint="provider_save_hook",
482
491
  ),
483
492
  ResearchTableProviderContract(
484
493
  key="email_finder",
485
494
  display_name="Email Finder",
486
495
  kind="enrichment",
496
+ behavior_class="standard_enrichment",
487
497
  provider_aliases=("smart_email_finder", "email_validator", "email_finder"),
488
498
  origin_aliases=("email_finder",),
489
499
  recipe_type="email_finder",
@@ -552,6 +562,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
552
562
  key="phone_finder",
553
563
  display_name="Phone Finder",
554
564
  kind="enrichment",
565
+ behavior_class="standard_enrichment",
555
566
  provider_aliases=("smart_phone_finder", "phone_validator", "phone_finder"),
556
567
  origin_aliases=("phone_finder",),
557
568
  recipe_type="phone_finder",
@@ -626,6 +637,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
626
637
  key="lead_finder",
627
638
  display_name="Lead Finder",
628
639
  kind="enrichment",
640
+ behavior_class="standard_enrichment",
629
641
  provider_aliases=("lead_finder",),
630
642
  recipe_type="lead_finder",
631
643
  recipe_payload={
@@ -706,6 +718,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
706
718
  key="add_to_crm",
707
719
  display_name="Add to Leads",
708
720
  kind="enrichment",
721
+ behavior_class="action_enrichment",
709
722
  provider_aliases=("add_to_crm",),
710
723
  recipe_type="add_to_crm",
711
724
  recipe_payload={
@@ -794,12 +807,14 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
794
807
  ],
795
808
  },
796
809
  execution_policy=_ADD_TO_CRM_POLICY,
810
+ readiness_strategy="add_to_crm",
797
811
  is_action_provider=True,
798
812
  ),
799
813
  ResearchTableProviderContract(
800
814
  key="sync_to_table",
801
815
  display_name="Sync to Table",
802
816
  kind="enrichment",
817
+ behavior_class="action_enrichment",
803
818
  provider_aliases=("sync_to_table",),
804
819
  recipe_type="sync_to_table",
805
820
  recipe_payload={
@@ -904,12 +919,14 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
904
919
  },
905
920
  execution_policy=_SYNC_TO_TABLE_POLICY,
906
921
  dispatch_strategy="sync_to_table_prefilter",
922
+ readiness_strategy="sync_to_table",
907
923
  is_action_provider=True,
908
924
  ),
909
925
  ResearchTableProviderContract(
910
926
  key="add_to_sequence",
911
927
  display_name="Add to Sequence",
912
928
  kind="enrichment",
929
+ behavior_class="action_enrichment",
913
930
  provider_aliases=("add_to_sequence",),
914
931
  recipe_type="add_to_sequence",
915
932
  recipe_payload={
@@ -972,12 +989,14 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
972
989
  ],
973
990
  },
974
991
  execution_policy=_ADD_TO_SEQUENCE_POLICY,
992
+ readiness_strategy="add_to_sequence",
975
993
  is_action_provider=True,
976
994
  ),
977
995
  ResearchTableProviderContract(
978
996
  key="http_request",
979
997
  display_name="HTTP Request",
980
998
  kind="enrichment",
999
+ behavior_class="standard_enrichment",
981
1000
  provider_aliases=("http_request",),
982
1001
  recipe_type="http_request",
983
1002
  recipe_payload={
@@ -998,7 +1017,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
998
1017
  },
999
1018
  recipe_notes=(
1000
1019
  "Use {{column_key}} placeholders in config.url, config.headers, and config.body to reference row values.",
1001
- "Use {{secrets.name}} to resolve a workspace secret or active org integration credential by provider slug.",
1020
+ "Use {{secrets.name}} to resolve a workspace secret by name.",
1002
1021
  "body can be null, a string template, or an object whose values are templated and sent as JSON.",
1003
1022
  "The stored cell value is the parsed response body (JSON or text), not the full transport envelope.",
1004
1023
  "Preview the resolved request with `autotouch columns test-http-request --table-id <TABLE_ID> --data-file column.json` before creating or running the column.",
@@ -1038,7 +1057,7 @@ _PROVIDER_CONTRACTS: Tuple[ResearchTableProviderContract, ...] = (
1038
1057
  composition_contract={
1039
1058
  "consumes": {
1040
1059
  "kind": "row_data",
1041
- "shape": "{{column_key}} templates resolved from row cell values plus optional {{secrets.name}} org credentials",
1060
+ "shape": "{{column_key}} templates resolved from row cell values plus optional {{secrets.name}} workspace secrets",
1042
1061
  },
1043
1062
  "produces": {
1044
1063
  "kind": "json",
@@ -1308,7 +1327,7 @@ def validate_column_provider_contract(
1308
1327
  raise ProviderContractValidationError(
1309
1328
  "invalid_field",
1310
1329
  "http_request config.headers must be an object when provided.",
1311
- hint="Set config.headers to a JSON object such as {\"Authorization\": \"Bearer {{secrets.provider}}\"}.",
1330
+ hint="Set config.headers to a JSON object such as {\"Authorization\": \"Bearer {{secrets.openai_api_key}}\"}.",
1312
1331
  )
1313
1332
  body = cfg.get("body")
1314
1333
  if body is not None and not isinstance(body, (str, dict)):
@@ -1355,3 +1374,74 @@ def automation_workflow_blueprints() -> Dict[str, Dict[str, Any]]:
1355
1374
 
1356
1375
  def action_provider_keys() -> Tuple[str, ...]:
1357
1376
  return tuple(contract.key for contract in _PROVIDER_CONTRACTS if contract.is_action_provider)
1377
+
1378
+
1379
+ def behavior_class_keys(behavior_class: str) -> Tuple[str, ...]:
1380
+ normalized = _normalize(behavior_class)
1381
+ return tuple(
1382
+ contract.key
1383
+ for contract in _PROVIDER_CONTRACTS
1384
+ if _normalize(contract.behavior_class) == normalized
1385
+ )
1386
+
1387
+
1388
+ def orchestrated_runtime_provider_keys(*, include_formatter: bool = False) -> Tuple[str, ...]:
1389
+ providers: List[str] = []
1390
+ for contract in _PROVIDER_CONTRACTS:
1391
+ policy = contract.execution_policy
1392
+ if not policy:
1393
+ continue
1394
+ normalized_behavior = _normalize(contract.behavior_class)
1395
+ if normalized_behavior == "formatter":
1396
+ if include_formatter:
1397
+ providers.append(policy.orchestrator_provider)
1398
+ continue
1399
+ if contract.key == "llm":
1400
+ providers.extend(["gemini", "xai"])
1401
+ continue
1402
+ providers.append(policy.orchestrator_provider)
1403
+ return tuple(dict.fromkeys(provider for provider in providers if provider))
1404
+
1405
+
1406
+ def resolve_provider_behavior_class(
1407
+ column: Dict[str, Any],
1408
+ config: Optional[Dict[str, Any]],
1409
+ ) -> Optional[str]:
1410
+ contract = resolve_effective_provider_contract(column, config)
1411
+ if not contract:
1412
+ return None
1413
+ return contract.behavior_class
1414
+
1415
+
1416
+ def should_resolve_managed_llm_model(
1417
+ column: Dict[str, Any],
1418
+ config: Optional[Dict[str, Any]],
1419
+ ) -> bool:
1420
+ contract = resolve_effective_provider_contract(column, config)
1421
+ if not contract:
1422
+ return False
1423
+ return contract.key == "llm" and _normalize(column.get("origin")) == "ai"
1424
+
1425
+
1426
+ def resolve_runtime_orchestrator_provider(
1427
+ column: Dict[str, Any],
1428
+ config: Optional[Dict[str, Any]],
1429
+ ) -> Optional[str]:
1430
+ contract = resolve_effective_provider_contract(column, config)
1431
+ if not contract or not contract.execution_policy:
1432
+ return None
1433
+ if _normalize(contract.behavior_class) == "formatter":
1434
+ return None
1435
+ if contract.key == "llm":
1436
+ runtime_provider = _normalize((config or {}).get("provider"))
1437
+ if runtime_provider in {"gemini", "xai"}:
1438
+ return runtime_provider
1439
+ return None
1440
+ return contract.execution_policy.orchestrator_provider
1441
+
1442
+
1443
+ def uses_orchestrated_bulk_run(
1444
+ column: Dict[str, Any],
1445
+ config: Optional[Dict[str, Any]],
1446
+ ) -> bool:
1447
+ return resolve_runtime_orchestrator_provider(column, config) is not None
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "autotouch-cli"
7
- version = "0.2.47"
7
+ version = "0.2.48"
8
8
  description = "Autotouch Smart Table CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes