fruxon 2.0.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. {fruxon-2.0.1 → fruxon-2.1.0}/HISTORY.md +106 -0
  2. {fruxon-2.0.1 → fruxon-2.1.0}/PKG-INFO +6 -1
  3. {fruxon-2.0.1 → fruxon-2.1.0}/README.md +5 -0
  4. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/__init__.py +6 -0
  5. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/_version.py +2 -2
  6. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/__init__.py +1 -0
  7. fruxon-2.1.0/src/fruxon/cli/agents_voice_calls.py +379 -0
  8. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/examples.py +27 -0
  9. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/integrations.py +298 -1
  10. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/llm_providers.py +615 -0
  11. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/messages.py +46 -7
  12. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_ledger.py +144 -3
  13. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/fruxon.py +376 -3
  14. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/models.py +94 -2
  15. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-build-agent/SKILL.md +25 -3
  16. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-create-integration/SKILL.md +22 -11
  17. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-debug-trace/SKILL.md +7 -0
  18. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-meet/SKILL.md +4 -0
  19. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_client.py +47 -0
  20. fruxon-2.1.0/tests/test_integrations_connect_cli.py +338 -0
  21. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_llm_provider_configs_cli.py +255 -0
  22. fruxon-2.1.0/tests/test_llm_providers_connect_cli.py +314 -0
  23. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_messages.py +20 -0
  24. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_ledger.py +147 -0
  25. fruxon-2.1.0/tests/test_voice_calls.py +288 -0
  26. {fruxon-2.0.1 → fruxon-2.1.0}/.gitignore +0 -0
  27. {fruxon-2.0.1 → fruxon-2.1.0}/LICENSE +0 -0
  28. {fruxon-2.0.1 → fruxon-2.1.0}/pyproject.toml +0 -0
  29. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/__main__.py +0 -0
  30. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/_ssl.py +0 -0
  31. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/checks/__init__.py +0 -0
  32. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/checks/agent.py +0 -0
  33. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/checks/ledger.py +0 -0
  34. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/checks/references.py +0 -0
  35. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/_crash.py +0 -0
  36. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/_schema.py +0 -0
  37. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/_shared.py +0 -0
  38. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/_stream.py +0 -0
  39. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents.py +0 -0
  40. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_approvals.py +0 -0
  41. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_budget.py +0 -0
  42. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_channels.py +0 -0
  43. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_draft.py +0 -0
  44. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_evaluations.py +0 -0
  45. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_executions.py +0 -0
  46. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_improvements.py +0 -0
  47. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_lifecycle.py +0 -0
  48. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_memory.py +0 -0
  49. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_reply_style.py +0 -0
  50. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_revisions.py +0 -0
  51. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_sandbox.py +0 -0
  52. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_sandbox_test.py +0 -0
  53. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_slots.py +0 -0
  54. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_system_blocks.py +0 -0
  55. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_tests.py +0 -0
  56. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/agents_topics.py +0 -0
  57. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/applications.py +0 -0
  58. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/applications_entry_points.py +0 -0
  59. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/assets.py +0 -0
  60. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/auth.py +0 -0
  61. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/capabilities.py +0 -0
  62. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/completion.py +0 -0
  63. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/config.py +0 -0
  64. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/consult_pins.py +0 -0
  65. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/conversation_imports.py +0 -0
  66. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/dash.py +0 -0
  67. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/describe.py +0 -0
  68. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/doctor.py +0 -0
  69. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/environments.py +0 -0
  70. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/escalations.py +0 -0
  71. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/guides.py +0 -0
  72. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/keys.py +0 -0
  73. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/knowledge_bases.py +0 -0
  74. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/knowledge_documents.py +0 -0
  75. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/knowledge_notices.py +0 -0
  76. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/knowledge_sources.py +0 -0
  77. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/metrics.py +0 -0
  78. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/participants.py +0 -0
  79. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/pipelines.py +0 -0
  80. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/secrets.py +0 -0
  81. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/skills.py +0 -0
  82. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/storage.py +0 -0
  83. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/tools.py +0 -0
  84. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers.py +0 -0
  85. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_budget.py +0 -0
  86. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_check.py +0 -0
  87. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_ledger_stage_tests.py +0 -0
  88. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_questions.py +0 -0
  89. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/triggers_shape.py +0 -0
  90. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/cli/workspaces.py +0 -0
  91. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/credentials.py +0 -0
  92. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/device_auth.py +0 -0
  93. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/doctor.py +0 -0
  94. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/exceptions.py +0 -0
  95. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/flow_validation.py +0 -0
  96. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/output.py +0 -0
  97. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/params.py +0 -0
  98. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/sandbox_scenario.py +0 -0
  99. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/__init__.py +0 -0
  100. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-agent-mode/SKILL.md +0 -0
  101. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/skills/fruxon-use-integrations/SKILL.md +0 -0
  102. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/telemetry.py +0 -0
  103. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/__init__.py +0 -0
  104. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/app.py +0 -0
  105. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/demo.py +0 -0
  106. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/links.py +0 -0
  107. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/__init__.py +0 -0
  108. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/agent.py +0 -0
  109. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/base.py +0 -0
  110. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/home.py +0 -0
  111. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/ledger.py +0 -0
  112. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/loader.py +0 -0
  113. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/pickers.py +0 -0
  114. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/screens/trace.py +0 -0
  115. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/source.py +0 -0
  116. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/theme.py +0 -0
  117. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/views.py +0 -0
  118. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/tui/widgets.py +0 -0
  119. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/ui.py +0 -0
  120. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/update_check.py +0 -0
  121. {fruxon-2.0.1 → fruxon-2.1.0}/src/fruxon/validation.py +0 -0
  122. {fruxon-2.0.1 → fruxon-2.1.0}/tests/.test_durations.json +0 -0
  123. {fruxon-2.0.1 → fruxon-2.1.0}/tests/__init__.py +0 -0
  124. {fruxon-2.0.1 → fruxon-2.1.0}/tests/conftest.py +0 -0
  125. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_actor.py +0 -0
  126. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agent_lifecycle.py +0 -0
  127. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agent_revisions_list.py +0 -0
  128. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agent_slots.py +0 -0
  129. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agents_check_cli.py +0 -0
  130. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agents_revisions_cli.py +0 -0
  131. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_agents_sandbox.py +0 -0
  132. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_applications.py +0 -0
  133. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_approvals.py +0 -0
  134. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_assets.py +0 -0
  135. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_budgets.py +0 -0
  136. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_capabilities.py +0 -0
  137. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_channels.py +0 -0
  138. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_checks_agent.py +0 -0
  139. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_checks_ledger.py +0 -0
  140. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_cli.py +0 -0
  141. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_cli_base_url_routing.py +0 -0
  142. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_cli_crash.py +0 -0
  143. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_cli_root_flags.py +0 -0
  144. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_connect_nudge.py +0 -0
  145. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_consult.py +0 -0
  146. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_conversation_imports.py +0 -0
  147. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_credentials.py +0 -0
  148. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_dash_app.py +0 -0
  149. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_dash_cli.py +0 -0
  150. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_dash_client.py +0 -0
  151. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_dash_links.py +0 -0
  152. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_dash_source.py +0 -0
  153. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_describe.py +0 -0
  154. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_device_auth.py +0 -0
  155. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_docs_commands_exist.py +0 -0
  156. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_doctor.py +0 -0
  157. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_draft_bootstrap.py +0 -0
  158. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_draft_evaluate_cli.py +0 -0
  159. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_draft_pull_shape.py +0 -0
  160. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_draft_run_replay.py +0 -0
  161. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_draft_validate_cli.py +0 -0
  162. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_drafts.py +0 -0
  163. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_entry_points.py +0 -0
  164. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_environments.py +0 -0
  165. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_escalations.py +0 -0
  166. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_evaluations.py +0 -0
  167. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_execution_records.py +0 -0
  168. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_flow_validation.py +0 -0
  169. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_fruxon.py +0 -0
  170. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_guides.py +0 -0
  171. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_improvements.py +0 -0
  172. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_integration_configs_write_cli.py +0 -0
  173. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_integration_triggers_cli.py +0 -0
  174. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_integrations_authorize_cli.py +0 -0
  175. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_kb_trial_cli.py +0 -0
  176. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_knowledge_bases.py +0 -0
  177. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_knowledge_documents.py +0 -0
  178. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_knowledge_notices.py +0 -0
  179. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_knowledge_sources.py +0 -0
  180. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_managed_by.py +0 -0
  181. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_memory.py +0 -0
  182. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_metrics.py +0 -0
  183. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_online_llm_config_refs.py +0 -0
  184. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_online_prefetch_refs.py +0 -0
  185. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_online_secret_refs.py +0 -0
  186. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_output.py +0 -0
  187. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_params.py +0 -0
  188. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_participants.py +0 -0
  189. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_participants_write.py +0 -0
  190. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_pipelines.py +0 -0
  191. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_reply_style.py +0 -0
  192. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_sandbox_scenario.py +0 -0
  193. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_schema.py +0 -0
  194. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_schema_fetch.py +0 -0
  195. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_secrets.py +0 -0
  196. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_skills.py +0 -0
  197. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_ssl.py +0 -0
  198. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_storage.py +0 -0
  199. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_system_blocks.py +0 -0
  200. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_system_blocks_cli.py +0 -0
  201. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_telemetry.py +0 -0
  202. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_test_chats.py +0 -0
  203. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_topics.py +0 -0
  204. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_trigger_budgets.py +0 -0
  205. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers.py +0 -0
  206. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_check_cli.py +0 -0
  207. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_ledger_batch_views.py +0 -0
  208. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_ledger_stage_tests.py +0 -0
  209. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_questions.py +0 -0
  210. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_shape.py +0 -0
  211. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_triggers_write.py +0 -0
  212. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_tui_boundary.py +0 -0
  213. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_ui.py +0 -0
  214. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_update_check.py +0 -0
  215. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_validation.py +0 -0
  216. {fruxon-2.0.1 → fruxon-2.1.0}/tests/test_workspaces_cli.py +0 -0
@@ -1,5 +1,111 @@
1
1
  # History
2
2
 
3
+ ## Unreleased — read voice calls back
4
+
5
+ - **`fruxon agents voice-calls list <agent>`** lists the agent's Talk calls
6
+ from the Test lab, newest first. Each row has the status, language, why the
7
+ call ended, its turns and its length. Output is `table`, `json` or `id`.
8
+ - **`fruxon agents voice-calls get <agent> <call-id>`** shows one call turn by
9
+ turn: what the caller said, the whole reply, and what was heard of it. When
10
+ the caller cut in, `delivery` is `INTERRUPTED` and `spokenText` is the part
11
+ they heard. Each turn also carries `generation` and the run behind its reply
12
+ (`executionRecordId`, for `agents executions trace`). Output is `text`,
13
+ `table` or `json`.
14
+ - Client methods `list_voice_calls` and `get_voice_call` return the new
15
+ `VoiceCall` and `VoiceCallTurn`. Both need fruxon-backend #1537; an older
16
+ server answers 404.
17
+
18
+ ## Unreleased — one completion on an LLM config, with no agent
19
+
20
+ - **`fruxon llm-providers configs complete <provider> <config> --model M`**
21
+ sends a system prompt and a short conversation to a model through the
22
+ config's published revision and prints the reply, with no agent, session or
23
+ execution record (scope `llm_providers:test`; fruxon-backend `:complete`).
24
+ It answers "does this model follow that instruction?" — pass a platform
25
+ system block's text as `--system` and read the reply — without a test turn
26
+ that writes to a live agent. `--system` (text, `@file`, `-`; repeatable),
27
+ `-m [user:|assistant:]TEXT` (repeatable) or `--messages chat.json`,
28
+ `--temperature`, `--max-tokens` (server cap 8192), `--param k=v`. The reply
29
+ goes to stdout, model, finish reason, tokens and latency to stderr; `-o json`
30
+ passes the server's result through. A Fruxon-hosted provider is refused.
31
+
32
+ ## Unreleased — `fruxon messages list --reason EMAIL_THREAD_UNAVAILABLE`
33
+
34
+ - `--reason` takes the server's new `EMAIL_THREAD_UNAVAILABLE` (fruxon-backend
35
+ #1494): an email thread's pinned conversation could not take the message (its
36
+ topic is missing, abandoned or mismatched, or its session belongs to another
37
+ thread), so it was withheld, the Gmail thread labelled `Fruxon/Needs human`,
38
+ and it is never replayed. It was refused as a typo before reaching the server.
39
+ A server without it answers 400 for it.
40
+
41
+ ## Unreleased — a link to fill in an LLM provider's API key
42
+
43
+ - **`fruxon llm-providers connect <provider>`** creates a config for an LLM
44
+ provider and prints a credential link. A human opens it, signs in to Fruxon
45
+ and types the API key (Bedrock's access key pair, Vertex's service account
46
+ key); the page tests it with the provider and publishes the config, which an
47
+ agent pins as `provider.tenantConfigId`. So an agent building an agent through
48
+ the CLI hands the user a link instead of asking for the key, and never sees
49
+ it. `--config <id>` fills an existing config instead; `--name` and
50
+ `--param name=value` (a non-secret setting such as `region`; required ones
51
+ are checked, and a secret is refused, before anything is created) shape the
52
+ new one. A key the provider turns down saves nothing and five lock the link;
53
+ one it could not check is saved with a warning. The link opens only for a
54
+ workspace member whose role may set up model providers (`llm_providers:write`,
55
+ which the Developer preset carries); `--no-sign-in` mints one whoever holds it
56
+ can fill (Admin or Owner). `--for`, `--note` and `--expires-in-hours` go on
57
+ the link. A config the command created is deleted again when no link could be
58
+ minted for it. A provider sharing another's credential is pointed at its
59
+ owner.
60
+ - **`fruxon llm-providers link-status <provider> <config> <request>`** says
61
+ where that link stands — `OPEN`, `FILLED`, `REFUSED`, `EXPIRED`, `LOCKED` or
62
+ `WITHDRAWN` — and `--wait` waits until it is filled or stops working. Exits 0
63
+ for open or filled, 13 once it stopped working, 14 when `--wait` runs out.
64
+ - Client methods `create_llm_provider_config`, `delete_llm_provider_config`,
65
+ `create_llm_credential_link` and `get_llm_credential_link`.
66
+
67
+ ## Unreleased — a link to fill in an integration's credentials
68
+
69
+ - **`fruxon integrations connect <integration>`** creates a config for an
70
+ integration that takes an API key, a bearer token or a username and password,
71
+ and prints a credential link. A human opens it, signs in to Fruxon and types
72
+ the credential; the page tests it against the service and publishes the
73
+ config. So an agent building an agent through the CLI hands the user a link
74
+ instead of asking for the secret, and never sees it. `--config <id>` fills an
75
+ existing config instead; `--name`, `--auth-method` (when the integration
76
+ declares several methods a link can fill) and `--param name=value` (a
77
+ connection setting such as a subdomain; required ones are checked before
78
+ anything is created) shape the new one. The link opens only for a workspace
79
+ member whose role may set up integrations; `--no-sign-in` mints one whoever
80
+ holds it can fill. `--for`, `--note` and `--expires-in-hours` (1–720, default
81
+ 168) go on the link. A config the command created is deleted again when no
82
+ link could be minted for it. OAuth integrations are pointed at
83
+ `integrations authorize`. Needs `integrations:write`, which the default
84
+ login preset carries (fruxon-backend #1487); a `--no-sign-in` link also needs
85
+ `workspace:write` (Admin or Owner).
86
+ - Client methods `create_integration_config`, `delete_integration_config` and
87
+ `create_credential_link`.
88
+
89
+ ## Unreleased — `fruxon messages list --reason` takes every withhold reason
90
+
91
+ - `--reason` accepted only `HUMAN_OWNED_CONVERSATION` and `ADMISSION_REFUSED`, so
92
+ `--reason OVER_BUDGET` and the other email-channel reasons were refused as typos
93
+ before reaching the server. It now takes every server `InboundWithholdReason`:
94
+ `NOT_ADDRESSED`, the email channel's `AUTO_REPLY`, `BULK_OR_LIST`, `BOUNCE`,
95
+ `OWN_ADDRESS`, `NOT_FOR_RECIPIENT`, `UNVERIFIED_SENDER`, `OVER_BUDGET`,
96
+ `THREAD_HAS_ANOTHER_SENDER`, `DELIVERY_DEFERRED_TOO_LONG`, and the new
97
+ `DRAFT_EDITED` (a customer wrote while a person was editing the agent's Gmail
98
+ draft; fruxon-backend #1488). A server without `DRAFT_EDITED` answers 400 for it.
99
+
100
+ ## Unreleased — a quality check that could not run is no failed reply
101
+
102
+ - `AgentJudgeActivity.pass_rate` is `passed / (passed + failed)`, as the server
103
+ now computes it (fruxon-backend #1482). A check that could not run (a model
104
+ error or a timeout) gave no verdict: it is counted in `errors` only, where it
105
+ used to count against the rate. A log-only agent whose checks errored gets
106
+ `None`, not 0, so the `fruxon dash` Quality check tile shows its average score.
107
+ The docstring said "errors included"; it now says what the field holds.
108
+
3
109
  ## Unreleased — `o` in `fruxon dash` opens the same page in the web app
4
110
 
5
111
  - `o` opens the web app on the exact tab or record behind what the console
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: fruxon
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: The Fruxon SDK is a lightweight Python client for integrating with the Fruxon platform.
5
5
  Project-URL: bugs, https://github.com/fruxon-ai/fruxon-sdk/issues
6
6
  Project-URL: changelog, https://github.com/fruxon-ai/fruxon-sdk/blob/main/HISTORY.md
@@ -104,6 +104,7 @@ Execution:
104
104
  | `fruxon escalations list/history/unhandled/policy/ack` | What happened when an agent handed a conversation to a person. `list` is the queue (live takeovers + degraded escalations nobody was reachable for); `unhandled` is the append-only ledger under it. **`history` is the record of closed console-routed takeovers** — those leave the queue, so `list --status ALL` answers `[]` about a conversation a human worked for half an hour. Read `humanObservedAt` before believing a `RESOLVED`: null means nobody was ever seen picking it up. `policy <agent>` resolves who the *next* escalation would reach — an empty ladder under `NATIVE_HANDOFF` is correct, the console supplies the human. |
105
105
  | `fruxon messages list` | The channel ledger — including inbound an agent was never shown. A **withheld** message (a human owns the chat in the source console, or admission refused the sender) never becomes a conversation turn, so it is in no transcript and the thread reads as a customer being ignored. `--delivery WITHHELD_PENDING` lists the ones nothing has ever acted on; nothing drains them. |
106
106
  | `fruxon agents sandbox open/turn/fire/resolve-input/stream/answer/close <session>` | Drive an agent-network sandbox end-to-end without real channels — send turns as participants, test-fire triggers, and watch the run (`stream`, NDJSON in agent mode). Sandbox **captures the reply and hard-blocks every real send**; `--await` makes consult/approval gates suspend so they can be resolved (`answer` for consults, `approvals respond` for approvals). `--draft` runs your unpublished draft instead of the deployed revision (`sandbox draft <session>` says which); `--confirm-writes` holds every create/update/delete tool call for approval, because sandbox does **not** block integration writes; a write that did not run (rejected, expired, or one the run could not pause for) shows on `stream` as `refused`. |
107
+ | `fruxon agents voice-calls list/get <agent>` | Read back the Test lab's Talk calls. `list` gives calls newest first (status, end reason, turns, length). `get <agent> <call-id>` gives the call turn by turn: the caller's transcript, the reply, what was heard of it (`delivery`; `spokenText` when the caller cut in), and each reply's `executionRecordId` for `agents executions trace`. Read-only; needs `executions:read`. |
107
108
  | `fruxon agents sandbox fork <agent> <message-id>` | Fork a real conversation at a transcript row (an `id` from `agents topics messages`) into a sandbox session already holding the history the agent had when it produced that reply. `--send` re-sends the customer's message against it — with `--draft` to test an edit before publishing — and holds writes for approval unless `--no-confirm-writes`. |
108
109
  | `fruxon agents sandbox test <file-or-dir>` | Run scenario-based e2e tests of an agent's network behavior. A scenario (YAML/JSON) declares `steps` (turns / trigger fires), `responders` (scripted consult/approval answers), and `expect` assertions (reply / routing / tools called or refused / no-leak / outcome); the runner drives a sandbox session and returns one verdict — exit 0 (pass) / 1 (fail) / 12 (bad file), with `--junit` for CI. An optional `setup` block provisions real resources first — an `asset` (uploaded + ingestion-waited), `participant`, or `agent` — templated as `${asset.catalog.id}` and **torn down afterwards even on failure** (`--keep` to inspect). Assertions are deterministic by default; `reply_judge: {metric, min_score}` adds an opt-in **semantic** check that scores the reply against a tenant eval metric. The thing an agent runs to prove the agent it built works. |
109
110
 
@@ -143,12 +144,15 @@ Integrations + tools:
143
144
  | `fruxon integrations list/get/create/update/verify/open` | Manage external integrations — the connections agents draw tools from. `create`/`update`/`verify` take a `--file` JSON body; `open` opens the dashboard. |
144
145
  | `fruxon integrations configs list/get/update/publish` | The per-integration auth/config records. `update --file` patches a config's draft (only the fields sent; `{"egressCountry": ""}` clears an egress pin) and prints it with secrets masked; `publish` makes the draft the revision tool calls resolve, asks first (`--yes` in agent mode), and prints the new revision's `id` and `version`, never the credentials. |
145
146
  | `fruxon integrations authorize <integration>` | Mint an application-level OAuth authorization URL to **connect** an integration — auto-detects its OAuth2 method (`--auth-method` to pick, `--scope`/`--config-param` to tune). OAuth needs a browser consent step, so the CLI hands you the link; a human clicks it, and the connection is saved as a tenant config a slot can pin. |
147
+ | `fruxon integrations connect <integration>` | Create a config for an API-key, token or password integration (Stripe, most REST APIs) and print a **credential link**: a human opens it, signs in to Fruxon, types the credential, and the page tests it and publishes the config. The secret never passes through the terminal or an agent driving the CLI. `--config <id>` fills an existing config, `--param name=value` sets a connection setting, `--no-sign-in` mints a link anyone holding it can fill (for a client without a Fruxon login), `--expires-in-hours` 1–720. Needs `integrations:write` (the default login preset); `--no-sign-in` also needs `workspace:write` (Admin or Owner). |
146
148
  | `fruxon integrations triggers <integration>` | List the event types an integration can fire an agent on — each descriptor's `id` is the `eventType` a trigger listens for, plus the `payloadFields` (dotted paths) a binding's `parameterMappings` can read. Discovery for wiring an inbound-event trigger without guessing. |
147
149
  | `fruxon integrations mcp …` | Inspect and enable the MCP server for an integration. |
148
150
  | `fruxon tools list/get/create/update/delete/run` | Manage the tools inside an integration. Integration-scoped. `get` and `run` select the tool with `--tool`; `run` executes it outside any agent — real credentials, real result — with `-p key=value`, and `-c` naming the config that supplies credentials. The tenant list API hides internal `knowledge_base` / `assets` tools; `tools list` recovers them by ID and lists them like any other (`--no-include-internal` for the raw server answer). |
149
151
  | `fruxon keys list/mint/revoke/delete/history/scopes` | Audit and revoke scoped tokens. Minting opens the dashboard so the secret never enters the CLI process. |
150
152
  | `fruxon llm-providers list/get/models` | Browse LLM providers and models supported at the tenant level. |
153
+ | `fruxon llm-providers connect <provider>` / `link-status` | Create a config for an LLM provider and print a **credential link**: a human opens it, signs in to Fruxon, types the API key (or access keys, or service account key), and the page tests it with the provider and publishes the config an agent pins as `provider.tenantConfigId`. The key never passes through the terminal or an agent driving the CLI. `--config <id>` fills an existing config, `--param name=value` sets a non-secret setting such as Bedrock's `region`, `--no-sign-in` mints a link anyone holding it can fill (Admin or Owner). `link-status <provider> <config> <request> [--wait]` says when it was filled. |
151
154
  | `fruxon llm-providers configs list/get/test/publish` | The workspace's saved LLM credentials — the `provider.tenantConfigId` an agent pins. `get` shows the draft (secrets masked), the published revision and last known health. `test` probes the draft on every provider surface that shares the credential (or just one, given that surface's provider id), one line per failing surface, exit 12 on failure (`llm_providers:test`). `publish` ships the draft as a new revision that every agent on the config switches to — it confirms, needs `--yes` in agent mode, and does not wait on a passing test (`llm_providers:write`). |
155
+ | `fruxon llm-providers configs complete <provider> <config> --model M` | One completion on a saved config's published revision, with no agent, session or execution — to see whether a model follows a prompt or a system block's instruction. `--system` (text, `@file`, `-`; repeatable), `-m [user:\|assistant:]TEXT` (repeatable) or `--messages chat.json`, `--temperature`, `--max-tokens` (server cap 8192), `--param k=v`. The reply goes to stdout, the model, finish reason, tokens and latency to stderr (`llm_providers:test`). Fruxon-hosted providers are refused. |
152
156
  | `fruxon assets create/list/get/wait/operations/delete` | Manage knowledge-base (RAG) assets an agent can query — upload local files, wait for async ingestion, inspect operations, and use the ids for `assetConfig.assetIds`. `delete` confirms + refuses without `--yes` in agent mode. |
153
157
  | `fruxon knowledge-bases list/get/create/update/publish/archive/delete` | The authored, reviewable corpus behind a `manual_knowledge` asset — **not** the asset itself, which is what gets searched (`get` prints the asset id as `backingAssetId`). **`publish` is the step that makes any of it findable**: only `PUBLISHED` documents travel in a snapshot, and only publishing the *base* moves one, so a base full of finished articles answers nothing until it runs. It returns on *acceptance*, not searchability — RAG ingests afterwards, so a pending publish state is normal. `list` hides archived bases, which keep answering for agents already attached to them; `delete` is refused while an agent revision still attaches one, and `archive` is the reversible path. |
154
158
  | `fruxon knowledge-bases usage <kb>` | Whether agents actually use the base: searches per hour, day or week (`--interval`), the passage tokens each search handed the agent, how many found nothing (split from searches that **could not fully search** it — index missing or still building, a phrasing failed), and which agents searched (up to 20 you can open, the rest counted together). `--origin test` counts test runs instead of production. Retrieved tokens are counted by the search index, so what the model read can be less when a large result is trimmed or offloaded. Searches are recorded from 15 October 2026 and kept 90 days at most, so a window reaching further back says where counting began rather than showing empty days. A 404 is a wrong id or a backend that predates the read. |
@@ -168,6 +172,7 @@ Integrations + tools:
168
172
  | `fruxon triggers check <trigger>` | Audit whether a work-shape automation can move its items, part by part in the order an item meets them: on and taking items in, the last pass read its source, each PROCESS stage's agent exists with a deployed revision and working credentials and models (a rejected credential's row says how many items failed there since), each ASK stage's contact is declared and bound on the asking agent and its oldest question has not waited past a fifth of its answer window, the outcome note's contact reaches a person, this week's spend against the weekly limit, and how many items died in the last 7 days. `{trigger, overall, checks[]}` like `agents check`; exits 12 only on a hard fail, warnings stay 0. Read-only. |
169
173
  | `fruxon triggers budget list/get/set/delete` | Spend limits on an automation **as a whole** (`--period DAILY/WEEKLY/MONTHLY`, UTC calendar windows), counting every production run it caused whichever agent made it. Once one is enforced they govern its runs, which then meet only these limits and not the agents' own; with none enforced, each stage stops at its agent's own limit. None by default and every one removable. An enforced limit refuses new work at the limit (stage runs, passes, a question's opening, the report) and holds the stages until the window resets, while turns of conversations it already opened still run (up to 110%); `--no-enforce` only alerts the Application's admins. Needs Editor. |
170
174
  | `fruxon triggers ledger redrive/ignore/settle/cancel-batch` | The operator verbs; all confirm and refuse without `--yes` in agent mode. `redrive` returns a DEAD or FAILED item to the queue with its attempts reset — settle any `UNKNOWN` effect first or the next attempt hits the same refusal. `ignore` excludes an item for a **required** reason, which is the only thing separating IGNORED from DEAD later. `settle` answers an effect the platform could not confirm (`--landed` / `--did-not-land` + `--reason`); wrong in the second direction duplicates the write. `cancel-batch` calls off a question — the items go back to READY and a later pass re-batches them. |
175
+ | `fruxon triggers ledger admit` | Start one item by hand on an automation whose work shape declares `onDemand`. `--set path=value` / `path:=<json>` (dotted paths nest) or `--data-file`; the server checks the declared inputs and refuses credential-named keys. The key — `--key`, or composed from the shape's `keyPaths` — is the whole idempotency: the same key again returns the existing item **unchanged** (`created: false`), whatever its status. Needs `triggers:fire`. |
171
176
  | `fruxon triggers ledger set-data` | Correct a parked (DEAD / FAILED / IGNORED) item's `data` before re-driving it — the value a stage recorded wrong, such as an ASK answer written as `SKIP`, which a plain re-drive would route on again. `--set path=value` (or `path:=<json>`, repeatable) on a top-level key the item carries or a path the shape declares (`produces`, `answeredWhenPath`); a misspelled key is refused with the settable list rather than added. `--reason` is required and lands on the item's history beside every old → new value. `--redrive` re-drives in the same transaction; `redrive` and `redrive-many` take `--set` too. |
172
177
  | `fruxon triggers ledger redrive-many/ignore-many` | The same two verbs over a **selection** — `--id` (repeatable), `--stage`, `--status`, `--before`/`--after` (Unix ms). The CLI resolves the selection to a count under the verb's own eligibility, shows it, and the server acts on exactly that count (409 if the set changed). The count is the server's own whenever the endpoint's filters say exactly what the selection says (a `--status` or an `--ignore-reason`, with no `--id` and no `--before`/`--after`) — one request instead of walking every page of a 4,000-item ledger, and one fewer place for the two sides to disagree. `ignore-many --stage X` is how you drain a stage. When the selection is `--id` values, the result names every id it did **not** act on and why — not a work item, another automation's, or a status the verb cannot touch (usually a pass holding the claim). |
173
178
  | `fruxon triggers ledger exclusions` | Every reason items were set aside, with how many each holds — the list `--ignore-reason` is picked from, and usually the fastest way to see a prompt excluding a whole class of work it should not. `funnel` stops at `1,204 IGNORED`, which is a status and not something anyone can act on; an exclusion is a judgement a stage made under an instruction, so what you hold after revising it is a *reason*. Each count is exactly what a reason-scoped re-drive resolves, so the diagnosis and the fix use the same string. Reasons print whole and are never truncated — the filter matches the entire string, case-sensitively, so a shortened one selects nothing. A `(none recorded)` row predates the reason being kept on the item: those items are real, no reason filter can reach them, and their way back is `--id`. At most 200 distinct reasons come back. |
@@ -69,6 +69,7 @@ Execution:
69
69
  | `fruxon escalations list/history/unhandled/policy/ack` | What happened when an agent handed a conversation to a person. `list` is the queue (live takeovers + degraded escalations nobody was reachable for); `unhandled` is the append-only ledger under it. **`history` is the record of closed console-routed takeovers** — those leave the queue, so `list --status ALL` answers `[]` about a conversation a human worked for half an hour. Read `humanObservedAt` before believing a `RESOLVED`: null means nobody was ever seen picking it up. `policy <agent>` resolves who the *next* escalation would reach — an empty ladder under `NATIVE_HANDOFF` is correct, the console supplies the human. |
70
70
  | `fruxon messages list` | The channel ledger — including inbound an agent was never shown. A **withheld** message (a human owns the chat in the source console, or admission refused the sender) never becomes a conversation turn, so it is in no transcript and the thread reads as a customer being ignored. `--delivery WITHHELD_PENDING` lists the ones nothing has ever acted on; nothing drains them. |
71
71
  | `fruxon agents sandbox open/turn/fire/resolve-input/stream/answer/close <session>` | Drive an agent-network sandbox end-to-end without real channels — send turns as participants, test-fire triggers, and watch the run (`stream`, NDJSON in agent mode). Sandbox **captures the reply and hard-blocks every real send**; `--await` makes consult/approval gates suspend so they can be resolved (`answer` for consults, `approvals respond` for approvals). `--draft` runs your unpublished draft instead of the deployed revision (`sandbox draft <session>` says which); `--confirm-writes` holds every create/update/delete tool call for approval, because sandbox does **not** block integration writes; a write that did not run (rejected, expired, or one the run could not pause for) shows on `stream` as `refused`. |
72
+ | `fruxon agents voice-calls list/get <agent>` | Read back the Test lab's Talk calls. `list` gives calls newest first (status, end reason, turns, length). `get <agent> <call-id>` gives the call turn by turn: the caller's transcript, the reply, what was heard of it (`delivery`; `spokenText` when the caller cut in), and each reply's `executionRecordId` for `agents executions trace`. Read-only; needs `executions:read`. |
72
73
  | `fruxon agents sandbox fork <agent> <message-id>` | Fork a real conversation at a transcript row (an `id` from `agents topics messages`) into a sandbox session already holding the history the agent had when it produced that reply. `--send` re-sends the customer's message against it — with `--draft` to test an edit before publishing — and holds writes for approval unless `--no-confirm-writes`. |
73
74
  | `fruxon agents sandbox test <file-or-dir>` | Run scenario-based e2e tests of an agent's network behavior. A scenario (YAML/JSON) declares `steps` (turns / trigger fires), `responders` (scripted consult/approval answers), and `expect` assertions (reply / routing / tools called or refused / no-leak / outcome); the runner drives a sandbox session and returns one verdict — exit 0 (pass) / 1 (fail) / 12 (bad file), with `--junit` for CI. An optional `setup` block provisions real resources first — an `asset` (uploaded + ingestion-waited), `participant`, or `agent` — templated as `${asset.catalog.id}` and **torn down afterwards even on failure** (`--keep` to inspect). Assertions are deterministic by default; `reply_judge: {metric, min_score}` adds an opt-in **semantic** check that scores the reply against a tenant eval metric. The thing an agent runs to prove the agent it built works. |
74
75
 
@@ -108,12 +109,15 @@ Integrations + tools:
108
109
  | `fruxon integrations list/get/create/update/verify/open` | Manage external integrations — the connections agents draw tools from. `create`/`update`/`verify` take a `--file` JSON body; `open` opens the dashboard. |
109
110
  | `fruxon integrations configs list/get/update/publish` | The per-integration auth/config records. `update --file` patches a config's draft (only the fields sent; `{"egressCountry": ""}` clears an egress pin) and prints it with secrets masked; `publish` makes the draft the revision tool calls resolve, asks first (`--yes` in agent mode), and prints the new revision's `id` and `version`, never the credentials. |
110
111
  | `fruxon integrations authorize <integration>` | Mint an application-level OAuth authorization URL to **connect** an integration — auto-detects its OAuth2 method (`--auth-method` to pick, `--scope`/`--config-param` to tune). OAuth needs a browser consent step, so the CLI hands you the link; a human clicks it, and the connection is saved as a tenant config a slot can pin. |
112
+ | `fruxon integrations connect <integration>` | Create a config for an API-key, token or password integration (Stripe, most REST APIs) and print a **credential link**: a human opens it, signs in to Fruxon, types the credential, and the page tests it and publishes the config. The secret never passes through the terminal or an agent driving the CLI. `--config <id>` fills an existing config, `--param name=value` sets a connection setting, `--no-sign-in` mints a link anyone holding it can fill (for a client without a Fruxon login), `--expires-in-hours` 1–720. Needs `integrations:write` (the default login preset); `--no-sign-in` also needs `workspace:write` (Admin or Owner). |
111
113
  | `fruxon integrations triggers <integration>` | List the event types an integration can fire an agent on — each descriptor's `id` is the `eventType` a trigger listens for, plus the `payloadFields` (dotted paths) a binding's `parameterMappings` can read. Discovery for wiring an inbound-event trigger without guessing. |
112
114
  | `fruxon integrations mcp …` | Inspect and enable the MCP server for an integration. |
113
115
  | `fruxon tools list/get/create/update/delete/run` | Manage the tools inside an integration. Integration-scoped. `get` and `run` select the tool with `--tool`; `run` executes it outside any agent — real credentials, real result — with `-p key=value`, and `-c` naming the config that supplies credentials. The tenant list API hides internal `knowledge_base` / `assets` tools; `tools list` recovers them by ID and lists them like any other (`--no-include-internal` for the raw server answer). |
114
116
  | `fruxon keys list/mint/revoke/delete/history/scopes` | Audit and revoke scoped tokens. Minting opens the dashboard so the secret never enters the CLI process. |
115
117
  | `fruxon llm-providers list/get/models` | Browse LLM providers and models supported at the tenant level. |
118
+ | `fruxon llm-providers connect <provider>` / `link-status` | Create a config for an LLM provider and print a **credential link**: a human opens it, signs in to Fruxon, types the API key (or access keys, or service account key), and the page tests it with the provider and publishes the config an agent pins as `provider.tenantConfigId`. The key never passes through the terminal or an agent driving the CLI. `--config <id>` fills an existing config, `--param name=value` sets a non-secret setting such as Bedrock's `region`, `--no-sign-in` mints a link anyone holding it can fill (Admin or Owner). `link-status <provider> <config> <request> [--wait]` says when it was filled. |
116
119
  | `fruxon llm-providers configs list/get/test/publish` | The workspace's saved LLM credentials — the `provider.tenantConfigId` an agent pins. `get` shows the draft (secrets masked), the published revision and last known health. `test` probes the draft on every provider surface that shares the credential (or just one, given that surface's provider id), one line per failing surface, exit 12 on failure (`llm_providers:test`). `publish` ships the draft as a new revision that every agent on the config switches to — it confirms, needs `--yes` in agent mode, and does not wait on a passing test (`llm_providers:write`). |
120
+ | `fruxon llm-providers configs complete <provider> <config> --model M` | One completion on a saved config's published revision, with no agent, session or execution — to see whether a model follows a prompt or a system block's instruction. `--system` (text, `@file`, `-`; repeatable), `-m [user:\|assistant:]TEXT` (repeatable) or `--messages chat.json`, `--temperature`, `--max-tokens` (server cap 8192), `--param k=v`. The reply goes to stdout, the model, finish reason, tokens and latency to stderr (`llm_providers:test`). Fruxon-hosted providers are refused. |
117
121
  | `fruxon assets create/list/get/wait/operations/delete` | Manage knowledge-base (RAG) assets an agent can query — upload local files, wait for async ingestion, inspect operations, and use the ids for `assetConfig.assetIds`. `delete` confirms + refuses without `--yes` in agent mode. |
118
122
  | `fruxon knowledge-bases list/get/create/update/publish/archive/delete` | The authored, reviewable corpus behind a `manual_knowledge` asset — **not** the asset itself, which is what gets searched (`get` prints the asset id as `backingAssetId`). **`publish` is the step that makes any of it findable**: only `PUBLISHED` documents travel in a snapshot, and only publishing the *base* moves one, so a base full of finished articles answers nothing until it runs. It returns on *acceptance*, not searchability — RAG ingests afterwards, so a pending publish state is normal. `list` hides archived bases, which keep answering for agents already attached to them; `delete` is refused while an agent revision still attaches one, and `archive` is the reversible path. |
119
123
  | `fruxon knowledge-bases usage <kb>` | Whether agents actually use the base: searches per hour, day or week (`--interval`), the passage tokens each search handed the agent, how many found nothing (split from searches that **could not fully search** it — index missing or still building, a phrasing failed), and which agents searched (up to 20 you can open, the rest counted together). `--origin test` counts test runs instead of production. Retrieved tokens are counted by the search index, so what the model read can be less when a large result is trimmed or offloaded. Searches are recorded from 15 October 2026 and kept 90 days at most, so a window reaching further back says where counting began rather than showing empty days. A 404 is a wrong id or a backend that predates the read. |
@@ -133,6 +137,7 @@ Integrations + tools:
133
137
  | `fruxon triggers check <trigger>` | Audit whether a work-shape automation can move its items, part by part in the order an item meets them: on and taking items in, the last pass read its source, each PROCESS stage's agent exists with a deployed revision and working credentials and models (a rejected credential's row says how many items failed there since), each ASK stage's contact is declared and bound on the asking agent and its oldest question has not waited past a fifth of its answer window, the outcome note's contact reaches a person, this week's spend against the weekly limit, and how many items died in the last 7 days. `{trigger, overall, checks[]}` like `agents check`; exits 12 only on a hard fail, warnings stay 0. Read-only. |
134
138
  | `fruxon triggers budget list/get/set/delete` | Spend limits on an automation **as a whole** (`--period DAILY/WEEKLY/MONTHLY`, UTC calendar windows), counting every production run it caused whichever agent made it. Once one is enforced they govern its runs, which then meet only these limits and not the agents' own; with none enforced, each stage stops at its agent's own limit. None by default and every one removable. An enforced limit refuses new work at the limit (stage runs, passes, a question's opening, the report) and holds the stages until the window resets, while turns of conversations it already opened still run (up to 110%); `--no-enforce` only alerts the Application's admins. Needs Editor. |
135
139
  | `fruxon triggers ledger redrive/ignore/settle/cancel-batch` | The operator verbs; all confirm and refuse without `--yes` in agent mode. `redrive` returns a DEAD or FAILED item to the queue with its attempts reset — settle any `UNKNOWN` effect first or the next attempt hits the same refusal. `ignore` excludes an item for a **required** reason, which is the only thing separating IGNORED from DEAD later. `settle` answers an effect the platform could not confirm (`--landed` / `--did-not-land` + `--reason`); wrong in the second direction duplicates the write. `cancel-batch` calls off a question — the items go back to READY and a later pass re-batches them. |
140
+ | `fruxon triggers ledger admit` | Start one item by hand on an automation whose work shape declares `onDemand`. `--set path=value` / `path:=<json>` (dotted paths nest) or `--data-file`; the server checks the declared inputs and refuses credential-named keys. The key — `--key`, or composed from the shape's `keyPaths` — is the whole idempotency: the same key again returns the existing item **unchanged** (`created: false`), whatever its status. Needs `triggers:fire`. |
136
141
  | `fruxon triggers ledger set-data` | Correct a parked (DEAD / FAILED / IGNORED) item's `data` before re-driving it — the value a stage recorded wrong, such as an ASK answer written as `SKIP`, which a plain re-drive would route on again. `--set path=value` (or `path:=<json>`, repeatable) on a top-level key the item carries or a path the shape declares (`produces`, `answeredWhenPath`); a misspelled key is refused with the settable list rather than added. `--reason` is required and lands on the item's history beside every old → new value. `--redrive` re-drives in the same transaction; `redrive` and `redrive-many` take `--set` too. |
137
142
  | `fruxon triggers ledger redrive-many/ignore-many` | The same two verbs over a **selection** — `--id` (repeatable), `--stage`, `--status`, `--before`/`--after` (Unix ms). The CLI resolves the selection to a count under the verb's own eligibility, shows it, and the server acts on exactly that count (409 if the set changed). The count is the server's own whenever the endpoint's filters say exactly what the selection says (a `--status` or an `--ignore-reason`, with no `--id` and no `--before`/`--after`) — one request instead of walking every page of a 4,000-item ledger, and one fewer place for the two sides to disagree. `ignore-many --stage X` is how you drain a stage. When the selection is `--id` values, the result names every id it did **not** act on and why — not a work item, another automation's, or a status the verb cannot touch (usually a pass holding the claim). |
138
143
  | `fruxon triggers ledger exclusions` | Every reason items were set aside, with how many each holds — the list `--ignore-reason` is picked from, and usually the fastest way to see a prompt excluding a whole class of work it should not. `funnel` stops at `1,204 IGNORED`, which is a status and not something anyone can act on; an exclusion is a judgement a stage made under an instruction, so what you hold after revising it is a *reason*. Each count is exactly what a reason-scoped re-drive resolves, so the diagnosis and the fix use the same string. Reasons print whole and are never truncated — the filter matches the entire string, case-sensitively, so a shortened one selects nothing. A `(none recorded)` row predates the reason being kept on the item: those items are real, no reason filter can reach them, and their way back is `--id`. At most 200 distinct reasons come back. |
@@ -80,6 +80,7 @@ from fruxon.models import (
80
80
  LedgerFunnelCell,
81
81
  LedgerGatheringGroup,
82
82
  LedgerItem,
83
+ LedgerItemAdmission,
83
84
  LedgerItemPoint,
84
85
  LedgerItemTimeseries,
85
86
  LedgerItemTransition,
@@ -123,6 +124,8 @@ from fruxon.models import (
123
124
  TriggerParameterMapping,
124
125
  TriggerRevision,
125
126
  UnhandledEscalation,
127
+ VoiceCall,
128
+ VoiceCallTurn,
126
129
  WorkShapeDoor,
127
130
  WorkShapeDoorConversation,
128
131
  WorkShapeDoorField,
@@ -212,6 +215,7 @@ __all__ = [
212
215
  "LedgerFunnelCell",
213
216
  "LedgerGatheringGroup",
214
217
  "LedgerItem",
218
+ "LedgerItemAdmission",
215
219
  "LedgerItemTransition",
216
220
  "LedgerPass",
217
221
  "LedgerPurgeResult",
@@ -250,6 +254,8 @@ __all__ = [
250
254
  "TriggerRevision",
251
255
  "UnhandledEscalation",
252
256
  "ValidationError",
257
+ "VoiceCall",
258
+ "VoiceCallTurn",
253
259
  "WorkShapeDoor",
254
260
  "WorkShapeDoorConversation",
255
261
  "WorkShapeDoorField",
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.0.1'
22
- __version_tuple__ = version_tuple = (2, 0, 1)
21
+ __version__ = version = '2.1.0'
22
+ __version_tuple__ = version_tuple = (2, 1, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -710,6 +710,7 @@ from fruxon.cli import agents_slots as _agents_slots # noqa: E402, F401
710
710
  from fruxon.cli import agents_system_blocks as _agents_system_blocks # noqa: E402, F401
711
711
  from fruxon.cli import agents_tests as _agents_tests # noqa: E402, F401
712
712
  from fruxon.cli import agents_topics as _agents_topics # noqa: E402, F401
713
+ from fruxon.cli import agents_voice_calls as _agents_voice_calls # noqa: E402, F401
713
714
  from fruxon.cli import applications as _applications # noqa: E402, F401
714
715
  from fruxon.cli import applications_entry_points as _applications_entry_points # noqa: E402, F401
715
716
  from fruxon.cli import assets as _assets # noqa: E402, F401