tinybird 0.0.1.dev280__tar.gz → 0.0.1.dev282__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.

Potentially problematic release.


This version of tinybird might be problematic. Click here for more details.

Files changed (147) hide show
  1. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/PKG-INFO +3 -2
  2. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/__cli__.py +2 -2
  3. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/agent.py +10 -3
  4. tinybird-0.0.1.dev282/tinybird/tb/modules/agent/models.py +61 -0
  5. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/prompts.py +49 -1
  6. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/local.py +24 -5
  7. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/local_common.py +22 -19
  8. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/login_common.py +18 -6
  9. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/PKG-INFO +3 -2
  10. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/requires.txt +2 -1
  11. tinybird-0.0.1.dev280/tinybird/tb/modules/agent/models.py +0 -35
  12. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/setup.cfg +0 -0
  13. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/__cli__.py +0 -0
  14. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/ch_utils/constants.py +0 -0
  15. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/ch_utils/engine.py +0 -0
  16. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/check_pypi.py +0 -0
  17. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/client.py +0 -0
  18. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/config.py +0 -0
  19. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/connectors.py +0 -0
  20. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/context.py +0 -0
  21. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datafile/common.py +0 -0
  22. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datafile/exceptions.py +0 -0
  23. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datafile/parse_connection.py +0 -0
  24. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datafile/parse_datasource.py +0 -0
  25. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datafile/parse_pipe.py +0 -0
  26. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/datatypes.py +0 -0
  27. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/feedback_manager.py +0 -0
  28. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/git_settings.py +0 -0
  29. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/prompts.py +0 -0
  30. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/sql.py +0 -0
  31. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/sql_template.py +0 -0
  32. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/sql_template_fmt.py +0 -0
  33. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/sql_toolset.py +0 -0
  34. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/syncasync.py +0 -0
  35. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/check_pypi.py +0 -0
  36. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/cli.py +0 -0
  37. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/client.py +0 -0
  38. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/config.py +0 -0
  39. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/__init__.py +0 -0
  40. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/animations.py +0 -0
  41. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/banner.py +0 -0
  42. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/command_agent.py +0 -0
  43. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/compactor.py +0 -0
  44. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/explore_agent.py +0 -0
  45. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/memory.py +0 -0
  46. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/testing_agent.py +0 -0
  47. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
  48. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
  49. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/append.py +0 -0
  50. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/build.py +0 -0
  51. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/datafile.py +0 -0
  52. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
  53. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
  54. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/diff_resource.py +0 -0
  55. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/execute_query.py +0 -0
  56. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
  57. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
  58. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/mock.py +0 -0
  59. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/plan.py +0 -0
  60. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/request_endpoint.py +0 -0
  61. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/run_command.py +0 -0
  62. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/secret.py +0 -0
  63. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/tools/test.py +0 -0
  64. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/agent/utils.py +0 -0
  65. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/build.py +0 -0
  66. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/build_common.py +0 -0
  67. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/cicd.py +0 -0
  68. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/cli.py +0 -0
  69. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/common.py +0 -0
  70. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/config.py +0 -0
  71. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/connection.py +0 -0
  72. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/copy.py +0 -0
  73. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/create.py +0 -0
  74. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/build.py +0 -0
  75. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/build_common.py +0 -0
  76. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
  77. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
  78. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/diff.py +0 -0
  79. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/fixture.py +0 -0
  80. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/format_common.py +0 -0
  81. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
  82. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
  83. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
  84. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/playground.py +0 -0
  85. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datafile/pull.py +0 -0
  86. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/datasource.py +0 -0
  87. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/deployment.py +0 -0
  88. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/deployment_common.py +0 -0
  89. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/deprecations.py +0 -0
  90. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/dev_server.py +0 -0
  91. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/endpoint.py +0 -0
  92. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/exceptions.py +0 -0
  93. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/feedback_manager.py +0 -0
  94. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/info.py +0 -0
  95. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/infra.py +0 -0
  96. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/job.py +0 -0
  97. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/llm.py +0 -0
  98. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/llm_utils.py +0 -0
  99. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/login.py +0 -0
  100. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/logout.py +0 -0
  101. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/materialization.py +0 -0
  102. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/mock.py +0 -0
  103. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/mock_common.py +0 -0
  104. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/open.py +0 -0
  105. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/pipe.py +0 -0
  106. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/project.py +0 -0
  107. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/regions.py +0 -0
  108. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/secret.py +0 -0
  109. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/secret_common.py +0 -0
  110. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/shell.py +0 -0
  111. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/sink.py +0 -0
  112. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/table.py +0 -0
  113. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/telemetry.py +0 -0
  114. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/test.py +0 -0
  115. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/test_common.py +0 -0
  116. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
  117. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
  118. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/token.py +0 -0
  119. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/watch.py +0 -0
  120. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/workspace.py +0 -0
  121. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb/modules/workspace_members.py +0 -0
  122. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli.py +0 -0
  123. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/auth.py +0 -0
  124. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/branch.py +0 -0
  125. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/cicd.py +0 -0
  126. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/cli.py +0 -0
  127. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/common.py +0 -0
  128. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/config.py +0 -0
  129. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/connection.py +0 -0
  130. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/datasource.py +0 -0
  131. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/exceptions.py +0 -0
  132. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/fmt.py +0 -0
  133. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/job.py +0 -0
  134. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/pipe.py +0 -0
  135. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/regions.py +0 -0
  136. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/tag.py +0 -0
  137. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/telemetry.py +0 -0
  138. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/test.py +0 -0
  139. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
  140. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
  141. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/workspace.py +0 -0
  142. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tb_cli_modules/workspace_members.py +0 -0
  143. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird/tornado_template.py +0 -0
  144. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/SOURCES.txt +0 -0
  145. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/dependency_links.txt +0 -0
  146. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/entry_points.txt +0 -0
  147. {tinybird-0.0.1.dev280 → tinybird-0.0.1.dev282}/tinybird.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev280
3
+ Version: 0.0.1.dev282
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -22,7 +22,8 @@ Requires-Dist: humanfriendly~=8.2
22
22
  Requires-Dist: plotext==5.3.2
23
23
  Requires-Dist: prompt_toolkit==3.0.48
24
24
  Requires-Dist: pydantic~=2.11.7
25
- Requires-Dist: pydantic-ai-slim[anthropic]~=0.4.2
25
+ Requires-Dist: pydantic-ai-slim[anthropic]~=0.5.0
26
+ Requires-Dist: pydantic-ai-slim[retries]~=0.5.0
26
27
  Requires-Dist: pyperclip==1.8.2
27
28
  Requires-Dist: pyyaml<6.1,>=6.0
28
29
  Requires-Dist: requests<3,>=2.28.1
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/forward/commands'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '0.0.1.dev280'
8
- __revision__ = 'e419ff7'
7
+ __version__ = '0.0.1.dev282'
8
+ __revision__ = '77eb85f'
@@ -16,7 +16,7 @@ from requests import Response
16
16
 
17
17
  from tinybird.tb.check_pypi import CheckPypi
18
18
  from tinybird.tb.client import TinyB
19
- from tinybird.tb.config import CURRENT_VERSION
19
+ from tinybird.tb.config import CURRENT_VERSION, get_display_cloud_host
20
20
  from tinybird.tb.modules.agent.animations import ThinkingAnimation
21
21
  from tinybird.tb.modules.agent.banner import display_banner
22
22
  from tinybird.tb.modules.agent.command_agent import CommandAgent
@@ -212,7 +212,12 @@ class TinybirdAgent:
212
212
 
213
213
  @self.agent.instructions
214
214
  def get_local_host(ctx: RunContext[TinybirdAgentContext]) -> str:
215
- return f"Tinybird Local host: {ctx.deps.local_host}"
215
+ return f"""
216
+ # Tinybird Local info:
217
+ - API Host: {ctx.deps.local_host}
218
+ - Token: {ctx.deps.local_token}
219
+ - UI Dashboard URL: {get_display_cloud_host(ctx.deps.local_host)}/{ctx.deps.workspace_name}
220
+ """
216
221
 
217
222
  @self.agent.instructions
218
223
  def get_cloud_host(ctx: RunContext[TinybirdAgentContext]) -> str:
@@ -230,12 +235,14 @@ class TinybirdAgent:
230
235
 
231
236
  region_provider = region["provider"]
232
237
  region_name = region["name"]
233
- return f"""Tinybird Cloud info (region details):
238
+ return f"""
239
+ # Tinybird Cloud info (region details):
234
240
  - API Host: {ctx.deps.host}
235
241
  - Workspace ID: {ctx.deps.workspace_id}
236
242
  - Workspace Name: {project.workspace_name} (in Tinybird Local the workspace name is the same because it is synced with Cloud)
237
243
  - Region provider: {region_provider}
238
244
  - Region name: {region_name}
245
+ - UI Dashboard URL: {get_display_cloud_host(ctx.deps.host)}/{ctx.deps.workspace_name}
239
246
  """
240
247
 
241
248
  @self.agent.instructions
@@ -0,0 +1,61 @@
1
+ from typing import Optional
2
+
3
+ from anthropic import AsyncAnthropic
4
+ from httpx import AsyncClient, HTTPStatusError
5
+ from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelName
6
+ from pydantic_ai.providers.anthropic import AnthropicProvider
7
+ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
8
+ from tenacity import AsyncRetrying, retry_if_exception_type, stop_after_attempt, wait_exponential
9
+
10
+
11
+ def create_retrying_client(token: str, workspace_id: str):
12
+ """Create a client with smart retry handling for multiple error types."""
13
+
14
+ def should_retry_status(response):
15
+ """Raise exceptions for retryable HTTP status codes."""
16
+ if response.status_code in (400, 429, 502, 503, 504):
17
+ response.raise_for_status() # This will raise HTTPStatusError
18
+
19
+ transport = AsyncTenacityTransport(
20
+ controller=AsyncRetrying(
21
+ # Retry on HTTP errors and connection issues
22
+ retry=retry_if_exception_type((HTTPStatusError, ConnectionError)),
23
+ # Smart waiting: respects Retry-After headers, falls back to exponential backoff
24
+ wait=wait_retry_after(fallback_strategy=wait_exponential(multiplier=1, max=60), max_wait=300),
25
+ # Stop after 5 attempts
26
+ stop=stop_after_attempt(5),
27
+ # Re-raise the last exception if all retries fail
28
+ reraise=True,
29
+ ),
30
+ validate_response=should_retry_status,
31
+ )
32
+ return AsyncClient(transport=transport, params={"token": token, "workspace_id": workspace_id})
33
+
34
+
35
+ def create_model(
36
+ token: str,
37
+ base_url: str,
38
+ workspace_id: str,
39
+ model: AnthropicModelName = "claude-4-sonnet-20250514",
40
+ run_id: Optional[str] = None,
41
+ ):
42
+ default_headers = {}
43
+ if run_id:
44
+ default_headers["X-Run-Id"] = run_id
45
+
46
+ client = AsyncAnthropic(
47
+ base_url=base_url,
48
+ http_client=create_retrying_client(token, workspace_id),
49
+ auth_token=token,
50
+ default_headers=default_headers,
51
+ )
52
+ return AnthropicModel(
53
+ model_name=model,
54
+ provider=AnthropicProvider(anthropic_client=client),
55
+ )
56
+
57
+
58
+ model_costs = {
59
+ "input_cost_per_token": 3e-06,
60
+ "output_cost_per_token": 1.5e-05,
61
+ }
@@ -5,7 +5,6 @@ from typing import Any
5
5
  from pydantic_ai import format_as_xml
6
6
 
7
7
  from tinybird.prompts import (
8
- copy_pipe_instructions,
9
8
  datasource_example,
10
9
  datasource_instructions,
11
10
  materialized_pipe_instructions,
@@ -35,6 +34,8 @@ available_commands = [
35
34
  "`tb sink ls`: List all sinks",
36
35
  "`tb workspace current`: Show the current workspace",
37
36
  "`tb workspace clear --yes`: Delete all resources in the workspace (Only available in Tinybird Local)",
37
+ "`tb local start --skip-new-version`: Start Tinybird Local container in non-interactive mode",
38
+ "`tb local restart --skip-new-version --yes`: Restart Tinybird Local container in non-interactive mode",
38
39
  ]
39
40
 
40
41
  plan_instructions = """
@@ -778,6 +779,37 @@ GCS_HMAC_SECRET {{ tb_secret("gcs_hmac_secret") }}
778
779
  ```
779
780
  """
780
781
 
782
+
783
+ copy_pipe_instructions = """
784
+ - Copy pipes should be created in the /copies folder.
785
+ - In a .pipe file you can define how to export the result of a Pipe to a Data Source, optionally with a schedule.
786
+ - Do not include `COPY_SCHEDULE` in the .pipe file unless is specifically requested by the user.
787
+ - `COPY_SCHEDULE` is a cron expression that defines the schedule of the copy pipe.
788
+ - `COPY_SCHEDULE` is optional and if not provided, the copy pipe will be executed only once.
789
+ - `TARGET_DATASOURCE` is the name of the Data Source to export the result to.
790
+ - `TYPE COPY` is the type of the pipe and it is mandatory for copy pipes.
791
+ - If the copy pipe uses parameters, you must include the `%` character and a newline on top of every query to be able to use the parameters.
792
+ - The content of the .pipe file must follow this format:
793
+
794
+ <copy_pipe_example>
795
+ DESCRIPTION Copy Pipe to export sales hour every hour to the sales_hour_copy Data Source
796
+
797
+ NODE daily_sales
798
+ SQL >
799
+ %
800
+ SELECT toStartOfDay(starting_date) day, country, sum(sales) as total_sales
801
+ FROM teams
802
+ WHERE
803
+ day BETWEEN toStartOfDay(now()) - interval 1 day AND toStartOfDay(now())
804
+ and country = {{ String(country, 'US')}}
805
+ GROUP BY day, country
806
+
807
+ TYPE COPY
808
+ TARGET_DATASOURCE sales_hour_copy
809
+ COPY_SCHEDULE 0 * * * *
810
+ </copy_pipe_example>
811
+ """
812
+
781
813
  agent_system_prompt = f"""
782
814
  You are a Tinybird Code, an agentic CLI that can help users to work with Tinybird.
783
815
 
@@ -867,6 +899,18 @@ where <scope> is one of the following: `TOKENS`, `ADMIN`, `ORG_DATASOURCES:READ`
867
899
  {sink_pipe_instructions}
868
900
 
869
901
  # Working with copy pipe files:
902
+
903
+ ## What are copy pipes?
904
+ Copy pipes capture the result of a pipe at a moment in time and write the result into a target data source.
905
+ They can be run on a schedule, or executed on demand.
906
+
907
+ ## Use copy pipes for:
908
+ - Event-sourced snapshots, such as change data capture (CDC).
909
+ - Copy data from Tinybird to another location in Tinybird to experiment.
910
+ - De-duplicate with snapshots.
911
+ - Copy pipes should not be confused with materialized views. While materialized views continuously update as new events are inserted, copy pipes generate a single snapshot at a specific point in time.
912
+
913
+ ## Copy pipe instructions
870
914
  {copy_pipe_instructions}
871
915
 
872
916
  # Working with SQL queries:
@@ -913,6 +957,10 @@ where <scope> is one of the following: `TOKENS`, `ADMIN`, `ORG_DATASOURCES:READ`
913
957
  # When asked about the files in the project:
914
958
  - You can rely in your own context to answer the question.
915
959
 
960
+ # When you need to copy/export data from the selected environment to a local file:
961
+ - Use `explore_data` tool to export data from the selected environment to a local file.
962
+ - Copy pipes do not copy data between environments, they are only used to copy data between data sources in the same environment.
963
+
916
964
  # Info
917
965
  Today is {datetime.now().strftime("%Y-%m-%d")}
918
966
  """
@@ -119,7 +119,13 @@ def remove() -> None:
119
119
  default=None,
120
120
  help="Path to the volumes directory. If not provided, the container data won't be persisted.",
121
121
  )
122
- def start(use_aws_creds: bool, volumes_path: str) -> None:
122
+ @click.option(
123
+ "--skip-new-version",
124
+ default=False,
125
+ is_flag=True,
126
+ help="Skip pulling the latest Tinybird Local image. Use directly your current local image.",
127
+ )
128
+ def start(use_aws_creds: bool, volumes_path: str, skip_new_version: bool) -> None:
123
129
  """Start Tinybird Local"""
124
130
  if volumes_path is not None:
125
131
  absolute_path = Path(volumes_path).absolute()
@@ -128,7 +134,7 @@ def start(use_aws_creds: bool, volumes_path: str) -> None:
128
134
 
129
135
  click.echo(FeedbackManager.highlight(message="» Starting Tinybird Local..."))
130
136
  docker_client = get_docker_client()
131
- start_tinybird_local(docker_client, use_aws_creds, volumes_path)
137
+ start_tinybird_local(docker_client, use_aws_creds, volumes_path, skip_new_version)
132
138
  click.echo(FeedbackManager.success(message="✓ Tinybird Local is ready!"))
133
139
 
134
140
 
@@ -144,7 +150,19 @@ def start(use_aws_creds: bool, volumes_path: str) -> None:
144
150
  default=None,
145
151
  help="Path to the volumes directory. If not provided, the container data won't be persisted.",
146
152
  )
147
- def restart(use_aws_creds: bool, volumes_path: str) -> None:
153
+ @click.option(
154
+ "--skip-new-version",
155
+ default=False,
156
+ is_flag=True,
157
+ help="Skip pulling the latest Tinybird Local image. Use directly your current local image.",
158
+ )
159
+ @click.option(
160
+ "--yes",
161
+ default=False,
162
+ is_flag=True,
163
+ help="Skip the confirmation prompt. If provided, the container will be restarted without asking for confirmation.",
164
+ )
165
+ def restart(use_aws_creds: bool, volumes_path: str, skip_new_version: bool, yes: bool) -> None:
148
166
  """Restart Tinybird Local"""
149
167
  if volumes_path is not None:
150
168
  absolute_path = Path(volumes_path).absolute()
@@ -153,9 +171,10 @@ def restart(use_aws_creds: bool, volumes_path: str) -> None:
153
171
 
154
172
  click.echo(FeedbackManager.highlight(message="» Restarting Tinybird Local..."))
155
173
  docker_client = get_docker_client()
156
- remove_tinybird_local(docker_client, volumes_path is not None)
174
+ persist_data = volumes_path is not None or yes
175
+ remove_tinybird_local(docker_client, persist_data)
157
176
  click.echo(FeedbackManager.info(message="✓ Tinybird Local stopped"))
158
- start_tinybird_local(docker_client, use_aws_creds, volumes_path)
177
+ start_tinybird_local(docker_client, use_aws_creds, volumes_path, skip_new_version)
159
178
  click.echo(FeedbackManager.success(message="✓ Tinybird Local is ready!"))
160
179
 
161
180
 
@@ -220,29 +220,32 @@ def start_tinybird_local(
220
220
  docker_client: DockerClient,
221
221
  use_aws_creds: bool,
222
222
  volumes_path: Optional[str] = None,
223
+ skip_new_version: bool = False,
223
224
  ) -> None:
224
225
  """Start the Tinybird container."""
225
226
  pull_show_prompt = False
226
227
  pull_required = False
227
- try:
228
- local_image = docker_client.images.get(TB_IMAGE_NAME)
229
- local_image_id = local_image.attrs["RepoDigests"][0].split("@")[1]
230
- remote_image = docker_client.images.get_registry_data(TB_IMAGE_NAME)
231
- pull_show_prompt = local_image_id != remote_image.id
232
- except Exception:
233
- pull_show_prompt = False
234
- pull_required = True
235
-
236
- if pull_show_prompt and click.confirm(
237
- FeedbackManager.warning(message="△ New version detected, download? [y/N]:"),
238
- show_default=False,
239
- prompt_suffix="",
240
- ):
241
- click.echo(FeedbackManager.info(message="* Downloading latest version of Tinybird Local..."))
242
- pull_required = True
243
-
244
- if pull_required:
245
- docker_client.images.pull(TB_IMAGE_NAME, platform="linux/amd64")
228
+
229
+ if not skip_new_version:
230
+ try:
231
+ local_image = docker_client.images.get(TB_IMAGE_NAME)
232
+ local_image_id = local_image.attrs["RepoDigests"][0].split("@")[1]
233
+ remote_image = docker_client.images.get_registry_data(TB_IMAGE_NAME)
234
+ pull_show_prompt = local_image_id != remote_image.id
235
+ except Exception:
236
+ pull_show_prompt = False
237
+ pull_required = True
238
+
239
+ if pull_show_prompt and click.confirm(
240
+ FeedbackManager.warning(message="△ New version detected, download? [y/N]:"),
241
+ show_default=False,
242
+ prompt_suffix="",
243
+ ):
244
+ click.echo(FeedbackManager.info(message="* Downloading latest version of Tinybird Local..."))
245
+ pull_required = True
246
+
247
+ if pull_required:
248
+ docker_client.images.pull(TB_IMAGE_NAME, platform="linux/amd64")
246
249
 
247
250
  environment = get_use_aws_creds() if use_aws_creds else {}
248
251
 
@@ -257,19 +257,31 @@ def open_url(url: str, *, new_tab: bool = False) -> bool:
257
257
 
258
258
  # 2. Inside WSL, prefer `wslview` if the user has it (wslu package).
259
259
  if _running_in_wsl() and shutil.which("wslview"):
260
- subprocess.Popen(["wslview", url])
261
- return True
260
+ try:
261
+ subprocess.Popen(["wslview", url])
262
+ return True
263
+ except Exception:
264
+ # wslview not found, continue to next fallback
265
+ pass
262
266
 
263
267
  # 3. Secondary WSL fallback use Windows **start** through cmd.exe.
264
268
  # Empty "" argument is required so long URLs are not treated as a window title.
265
269
  if _running_in_wsl():
266
- subprocess.Popen(["cmd.exe", "/c", "start", "", url])
267
- return True
270
+ try:
271
+ subprocess.Popen(["cmd.exe", "/c", "start", "", url])
272
+ return True
273
+ except Exception:
274
+ # cmd.exe not found, continue to next fallback
275
+ pass
268
276
 
269
277
  # 4. Unix last-ditch fallback xdg-open (most minimal container images have it)
270
278
  if shutil.which("xdg-open"):
271
- subprocess.Popen(["xdg-open", url])
272
- return True
279
+ try:
280
+ subprocess.Popen(["xdg-open", url])
281
+ return True
282
+ except Exception:
283
+ # xdg-open not found, continue to next fallback
284
+ pass
273
285
 
274
286
  # 5. If everything failed, let the caller know.
275
287
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev280
3
+ Version: 0.0.1.dev282
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -22,7 +22,8 @@ Requires-Dist: humanfriendly~=8.2
22
22
  Requires-Dist: plotext==5.3.2
23
23
  Requires-Dist: prompt_toolkit==3.0.48
24
24
  Requires-Dist: pydantic~=2.11.7
25
- Requires-Dist: pydantic-ai-slim[anthropic]~=0.4.2
25
+ Requires-Dist: pydantic-ai-slim[anthropic]~=0.5.0
26
+ Requires-Dist: pydantic-ai-slim[retries]~=0.5.0
26
27
  Requires-Dist: pyperclip==1.8.2
27
28
  Requires-Dist: pyyaml<6.1,>=6.0
28
29
  Requires-Dist: requests<3,>=2.28.1
@@ -13,7 +13,8 @@ humanfriendly~=8.2
13
13
  plotext==5.3.2
14
14
  prompt_toolkit==3.0.48
15
15
  pydantic~=2.11.7
16
- pydantic-ai-slim[anthropic]~=0.4.2
16
+ pydantic-ai-slim[anthropic]~=0.5.0
17
+ pydantic-ai-slim[retries]~=0.5.0
17
18
  pyperclip==1.8.2
18
19
  pyyaml<6.1,>=6.0
19
20
  requests<3,>=2.28.1
@@ -1,35 +0,0 @@
1
- from typing import Optional
2
-
3
- from anthropic import AsyncAnthropic
4
- from httpx import AsyncClient
5
- from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelName
6
- from pydantic_ai.providers.anthropic import AnthropicProvider
7
-
8
-
9
- def create_model(
10
- token: str,
11
- base_url: str,
12
- workspace_id: str,
13
- model: AnthropicModelName = "claude-4-sonnet-20250514",
14
- run_id: Optional[str] = None,
15
- ):
16
- default_headers = {}
17
- if run_id:
18
- default_headers["X-Run-Id"] = run_id
19
-
20
- client = AsyncAnthropic(
21
- base_url=base_url,
22
- http_client=AsyncClient(params={"token": token, "workspace_id": workspace_id}),
23
- auth_token=token,
24
- default_headers=default_headers,
25
- )
26
- return AnthropicModel(
27
- model_name=model,
28
- provider=AnthropicProvider(anthropic_client=client),
29
- )
30
-
31
-
32
- model_costs = {
33
- "input_cost_per_token": 3e-06,
34
- "output_cost_per_token": 1.5e-05,
35
- }