tinybird 0.0.1.dev264__py3-none-any.whl → 0.0.1.dev266__py3-none-any.whl

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.

tinybird/tb/__cli__.py CHANGED
@@ -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.dev264'
8
- __revision__ = '5cf9a41'
7
+ __version__ = '0.0.1.dev266'
8
+ __revision__ = 'b4193e9'
tinybird/tb/client.py CHANGED
@@ -547,12 +547,15 @@ class TinyB:
547
547
  populate_subset: bool = False,
548
548
  populate_condition: Optional[str] = None,
549
549
  truncate: bool = True,
550
+ on_demand_compute: bool = False,
550
551
  ):
551
552
  params: Dict[str, Any] = {"truncate": "true" if truncate else "false", "unlink_on_populate_error": "false"}
552
553
  if populate_subset:
553
554
  params.update({"populate_subset": populate_subset})
554
555
  if populate_condition:
555
556
  params.update({"populate_condition": populate_condition})
557
+ if on_demand_compute:
558
+ params.update({"on_demand_compute": "true"})
556
559
  response = self._req(f"/v0/pipes/{pipe_name}/nodes/{node_name}/population?{urlencode(params)}", method="POST")
557
560
  return response
558
561
 
@@ -867,9 +870,15 @@ class TinyB:
867
870
  data={"operation": "change_role", "users": users, "new_role": role},
868
871
  )
869
872
 
870
- def workspace(self, workspace_id: str, with_token: bool = False):
871
- params = {"with_token": "true" if with_token else "false"}
872
- return self._req(f"/v0/workspaces/{workspace_id}?{urlencode(params)}")
873
+ def workspace(
874
+ self, workspace_id: str, with_token: bool = False, with_organization: bool = False, version: str = "v0"
875
+ ):
876
+ params = {}
877
+ if with_token:
878
+ params["with_token"] = "true"
879
+ if with_organization:
880
+ params["with_organization"] = "true"
881
+ return self._req(f"/{version}/workspaces/{workspace_id}?{urlencode(params)}")
873
882
 
874
883
  def workspace_info(self, version: str = "v0") -> Dict[str, Any]:
875
884
  return self._req(f"/{version}/workspace")
@@ -877,6 +886,12 @@ class TinyB:
877
886
  def organization(self, organization_id: str):
878
887
  return self._req(f"/v0/organizations/{organization_id}")
879
888
 
889
+ def organization_limits(self, organization_id: str):
890
+ return self._req(f"/v1/billing/{organization_id}/limits")
891
+
892
+ def organization_subscription(self, organization_id: str):
893
+ return self._req(f"/v1/billing/{organization_id}/subscription")
894
+
880
895
  def create_organization(
881
896
  self,
882
897
  name: str,
@@ -3,6 +3,7 @@ import shlex
3
3
  import subprocess
4
4
  import sys
5
5
  import urllib.parse
6
+ import uuid
6
7
  from functools import partial
7
8
  from pathlib import Path
8
9
  from typing import Any, Optional
@@ -19,7 +20,7 @@ from tinybird.tb.modules.agent.animations import ThinkingAnimation
19
20
  from tinybird.tb.modules.agent.banner import display_banner
20
21
  from tinybird.tb.modules.agent.command_agent import CommandAgent
21
22
  from tinybird.tb.modules.agent.memory import clear_history, clear_messages, load_messages, save_messages
22
- from tinybird.tb.modules.agent.models import create_model, model_costs
23
+ from tinybird.tb.modules.agent.models import create_model
23
24
  from tinybird.tb.modules.agent.prompts import agent_system_prompt, load_custom_project_rules, resources_prompt
24
25
  from tinybird.tb.modules.agent.testing_agent import TestingAgent
25
26
  from tinybird.tb.modules.agent.tools.analyze import analyze_file, analyze_url
@@ -256,12 +257,12 @@ class TinybirdAgent:
256
257
  click.echo(result.output)
257
258
  self._echo_usage(config, result)
258
259
 
259
- async def run_iter(self, user_prompt: str, config: dict[str, Any]) -> None:
260
+ async def run_iter(self, user_prompt: str, config: dict[str, Any], model: Any) -> None:
260
261
  user_prompt = f"{user_prompt}\n\n{load_custom_project_rules(self.project.folder)}"
261
262
  self.thinking_animation.start()
262
263
  deps = self._build_agent_deps(config)
263
264
 
264
- async with self.agent.iter(user_prompt, deps=deps, message_history=self.messages) as agent_run:
265
+ async with self.agent.iter(user_prompt, deps=deps, message_history=self.messages, model=model) as agent_run:
265
266
  async for node in agent_run:
266
267
  if hasattr(node, "model_response"):
267
268
  for _i, part in enumerate(node.model_response.parts):
@@ -281,19 +282,32 @@ class TinybirdAgent:
281
282
  self._echo_usage(config, agent_run.result)
282
283
 
283
284
  def _echo_usage(self, config: dict[str, Any], result: AgentRunResult) -> None:
284
- if "@tinybird.co" in config.get("user_email", ""):
285
- usage = result.usage()
286
- request_tokens = usage.request_tokens or 0
287
- response_tokens = usage.response_tokens or 0
288
- total_tokens = usage.total_tokens or 0
289
- cost = (
290
- request_tokens * model_costs["input_cost_per_token"]
291
- + response_tokens * model_costs["output_cost_per_token"]
285
+ try:
286
+ client = _get_tb_client(config["user_token"], config["host"])
287
+ workspace_id = config.get("id", "")
288
+ workspace = client.workspace(workspace_id, with_organization=True, version="v1")
289
+ limits_data = client.organization_limits(workspace["organization"]["id"])
290
+ ai_requests_limits = limits_data.get("limits", {}).get("ai_requests", {})
291
+ current_ai_requests = ai_requests_limits.get("quantity", 0)
292
+ max_ai_requests = ai_requests_limits.get("max", 0)
293
+ if not max_ai_requests:
294
+ return
295
+ remaining_requests = max(max_ai_requests - current_ai_requests, 0)
296
+ warning_threshold = max_ai_requests * 0.8
297
+ if current_ai_requests >= warning_threshold:
298
+ message_color = FeedbackManager.warning
299
+ else:
300
+ message_color = FeedbackManager.gray
301
+
302
+ current_ai_requests = min(max_ai_requests, current_ai_requests)
303
+
304
+ click.echo(
305
+ message_color(
306
+ message=f"{remaining_requests} agent requests left ({current_ai_requests}/{max_ai_requests}). This message is informative. Limits will be enforced soon."
307
+ )
292
308
  )
293
- click.echo(f"Input tokens: {request_tokens}")
294
- click.echo(f"Output tokens: {response_tokens}")
295
- click.echo(f"Total tokens: {total_tokens}")
296
- click.echo(f"Cost: ${cost:.6f}")
309
+ except Exception:
310
+ pass
297
311
 
298
312
 
299
313
  def run_agent(
@@ -426,7 +440,9 @@ def run_agent(
426
440
  elif user_input.strip() == "":
427
441
  continue
428
442
  else:
429
- asyncio.run(agent.run_iter(user_input, config))
443
+ run_id = str(uuid.uuid4())
444
+ model = create_model(user_token, host, workspace_id, run_id=run_id)
445
+ asyncio.run(agent.run_iter(user_input, config, model))
430
446
  except AgentRunCancelled:
431
447
  click.echo(FeedbackManager.info(message="User cancelled the operation"))
432
448
  agent.add_message(
@@ -86,46 +86,19 @@ def display_banner():
86
86
  color_idx = 16 + (36 * r_idx) + (6 * g_idx) + b_idx
87
87
  return f"\033[38;5;{color_idx}m"
88
88
 
89
- # Define start and end colors for smooth gradient
90
- start_color = [0, 128, 128] # Deep teal
91
- end_color = [100, 190, 190] # Light turquoise (balanced green and blue)
89
+ # Define solid color (corresponding to #27f795)
90
+ solid_color = [39, 247, 149] # #27f795 in RGB
92
91
 
93
- # Print each line with gradient for modern terminals, solid color for limited terminals
92
+ # Print each line with solid color for all terminals
94
93
  for line in banner:
95
94
  colored_line = ""
95
+ color_code = rgb_to_ansi(*solid_color, use_truecolor=capabilities["truecolor"]) # type: ignore
96
96
 
97
- if capabilities["truecolor"]:
98
- # Use gradient for modern terminals
99
- non_space_chars = sum(1 for char in line if char != " ")
100
- char_count = 0
101
-
102
- for char in line:
103
- if char == " ":
104
- colored_line += char
105
- continue
106
-
107
- # Calculate smooth gradient position (0.0 to 1.0)
108
- if non_space_chars > 1:
109
- gradient_position = char_count / (non_space_chars - 1)
110
- else:
111
- gradient_position = 0
112
-
113
- # Interpolate color
114
- current_rgb = interpolate_color(start_color, end_color, gradient_position)
115
- color_code = rgb_to_ansi(*current_rgb, use_truecolor=True) # type: ignore
116
-
97
+ for char in line:
98
+ if char == " ":
99
+ colored_line += char
100
+ else:
117
101
  colored_line += f"{color_code}{char}"
118
- char_count += 1
119
- else:
120
- # Use solid color for limited terminals (like macOS Terminal)
121
- solid_color = start_color # Use the deep teal consistently
122
- color_code = rgb_to_ansi(*solid_color, use_truecolor=False) # type: ignore
123
-
124
- for char in line:
125
- if char == " ":
126
- colored_line += char
127
- else:
128
- colored_line += f"{color_code}{char}"
129
102
 
130
103
  click.echo(colored_line + reset)
131
104
  click.echo()
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from anthropic import AsyncAnthropic
2
4
  from httpx import AsyncClient
3
5
  from pydantic_ai.models.anthropic import AnthropicModel, AnthropicModelName
@@ -9,11 +11,17 @@ def create_model(
9
11
  base_url: str,
10
12
  workspace_id: str,
11
13
  model: AnthropicModelName = "claude-4-sonnet-20250514",
14
+ run_id: Optional[str] = None,
12
15
  ):
16
+ default_headers = {}
17
+ if run_id:
18
+ default_headers["X-Run-Id"] = run_id
19
+
13
20
  client = AsyncAnthropic(
14
21
  base_url=base_url,
15
22
  http_client=AsyncClient(params={"token": token, "workspace_id": workspace_id}),
16
23
  auth_token=token,
24
+ default_headers=default_headers,
17
25
  )
18
26
  return AnthropicModel(
19
27
  model_name=model,
@@ -704,7 +704,7 @@ def show_input(workspace_name: str) -> str:
704
704
  cursor=CursorShape.BLOCK,
705
705
  style=PromptStyle.from_dict(
706
706
  {
707
- "prompt": "#40a8a8 bold",
707
+ "prompt": "fg:#27f795 bold",
708
708
  "": "", # Normal color for user input
709
709
  }
710
710
  ),
@@ -87,6 +87,12 @@ def materialization_ls(ctx: click.Context, match: str, format_: str):
87
87
  default=False,
88
88
  help="Waits for populate jobs to finish, showing a progress bar. Disabled by default.",
89
89
  )
90
+ @click.option(
91
+ "--on-demand-compute",
92
+ is_flag=True,
93
+ default=False,
94
+ help="Use on-demand compute instances for the populate job.",
95
+ )
90
96
  @click.pass_context
91
97
  def pipe_populate(
92
98
  ctx: click.Context,
@@ -95,6 +101,7 @@ def pipe_populate(
95
101
  sql_condition: str,
96
102
  truncate: bool,
97
103
  wait: bool,
104
+ on_demand_compute: bool,
98
105
  ):
99
106
  """Populate the result of a Materialized Node into the target materialized view"""
100
107
 
@@ -121,7 +128,9 @@ def pipe_populate(
121
128
 
122
129
  node = materialized_ids[0]
123
130
 
124
- response = cl.populate_node(pipe_name, node, populate_condition=sql_condition, truncate=truncate)
131
+ response = cl.populate_node(
132
+ pipe_name, node, populate_condition=sql_condition, truncate=truncate, on_demand_compute=on_demand_compute
133
+ )
125
134
  if "job" not in response:
126
135
  raise CLIPipeException(response)
127
136
 
@@ -163,7 +163,7 @@ def create(ctx: Context) -> None:
163
163
 
164
164
  * Static Tokens do not have a TTL and can have any valid scope (ADMIN, TOKENS, or ORG_DATASOURCES:READ).
165
165
 
166
- * JWT tokens have a TTL and can only have the PIPES:READ scope.Their main use case is allow your users to call your endpoints without exposing your API key.
166
+ * JWT tokens have a TTL and can have PIPES:READ and DATASOURCES:READ scopes. Their main use case is allow your users to call your endpoints or read datasources without exposing your API key.
167
167
 
168
168
 
169
169
  Examples:
@@ -173,6 +173,8 @@ def create(ctx: Context) -> None:
173
173
  tb token create static my_static_token --scope TOKENS
174
174
 
175
175
  tb token create jwt my_jwt_token --ttl 1h --scope PIPES:READ --resource my_pipe
176
+
177
+ tb token create jwt my_jwt_token --ttl 1h --scope DATASOURCES:READ --resource my_datasource --filter "column = 'value'"
176
178
  """
177
179
 
178
180
 
@@ -182,16 +184,21 @@ def create(ctx: Context) -> None:
182
184
  @click.option(
183
185
  "--scope",
184
186
  multiple=True,
185
- type=click.Choice(["PIPES:READ"]),
187
+ type=click.Choice(["PIPES:READ", "DATASOURCES:READ"]),
186
188
  required=True,
187
- help="Scope of the token (only PIPES:READ is allowed for JWT tokens)",
189
+ help="Scope of the token (only PIPES:READ and DATASOURCES:READ are allowed for JWT tokens)",
188
190
  )
189
191
  @click.option("--resource", multiple=True, required=True, help="Resource associated with the scope")
190
192
  @click.option(
191
193
  "--fixed-params", multiple=True, help="Fixed parameters in key=value format, multiple values separated by commas"
192
194
  )
195
+ @click.option(
196
+ "--filter",
197
+ multiple=True,
198
+ help="SQL filter to apply when reading a datasource (only applicable for DATASOURCES:READ scope)",
199
+ )
193
200
  @click.pass_context
194
- def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, fixed_params) -> None:
201
+ def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, fixed_params, filter) -> None:
195
202
  """Create a JWT token with a TTL specify."""
196
203
 
197
204
  obj: Dict[str, Any] = ctx.ensure_object(dict)
@@ -205,6 +212,10 @@ def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, f
205
212
  if fixed_params and len(fixed_params) > len(scope):
206
213
  raise CLITokenException(FeedbackManager.error_number_of_fixed_params_and_resources_mismatch())
207
214
 
215
+ # Ensure the number of filters does not exceed the number of scope/resource pairs
216
+ if filter and len(filter) > len(scope):
217
+ raise CLITokenException("The number of SQL filters must match the number of scopes")
218
+
208
219
  # Parse fixed params
209
220
  parsed_fixed_params = parse_fixed_params(fixed_params) if fixed_params else []
210
221
 
@@ -213,15 +224,24 @@ def create_jwt_token(ctx: Context, name: str, ttl: timedelta, scope, resource, f
213
224
  for i, params in enumerate(parsed_fixed_params):
214
225
  fixed_params_list[i] = params
215
226
 
227
+ # Create a list of filters for each scope/resource pair, defaulting to None if not provided
228
+ filters_list: List[Optional[str]] = [None] * len(scope)
229
+ for i, f in enumerate(filter):
230
+ filters_list[i] = f
231
+
216
232
  scopes = []
217
- for sc, res, fparams in zip(scope, resource, fixed_params_list):
218
- scopes.append(
219
- {
220
- "type": sc,
221
- "resource": res,
222
- "fixed_params": fparams,
223
- }
224
- )
233
+ for sc, res, fparams, filter in zip(scope, resource, fixed_params_list, filters_list):
234
+ scope_data = {
235
+ "type": sc,
236
+ "resource": res,
237
+ }
238
+
239
+ if sc == "PIPES:READ" and fparams:
240
+ scope_data["fixed_params"] = fparams
241
+ elif sc == "DATASOURCES:READ" and filter:
242
+ scope_data["filter"] = filter
243
+
244
+ scopes.append(scope_data)
225
245
 
226
246
  try:
227
247
  response = client.create_jwt_token(name, expiration_time, scopes)
@@ -258,6 +278,7 @@ class DynamicOptionsCommand(click.Command):
258
278
  # Options
259
279
  dynamic_options_help += "Options:\n"
260
280
  dynamic_options_help += f" --scope [{','.join(valid_scopes)}] Scope for the token [Required]\n"
281
+ dynamic_options_help += " --resource TEXT Resource you want to associate the scope with\n"
261
282
  dynamic_options_help += " -h, --help Show this message and exit.\n"
262
283
 
263
284
  return dynamic_options_help
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev264
3
+ Version: 0.0.1.dev266
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -17,10 +17,10 @@ tinybird/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1w
17
17
  tinybird/datafile/parse_connection.py,sha256=tRyn2Rpr1TeWet5BXmMoQgaotbGdYep1qiTak_OqC5E,1825
18
18
  tinybird/datafile/parse_datasource.py,sha256=ssW8QeFSgglVFi3sDZj_HgkJiTJ2069v2JgqnH3CkDE,1825
19
19
  tinybird/datafile/parse_pipe.py,sha256=xf4m0Tw44QWJzHzAm7Z7FwUoUUtr7noMYjU1NiWnX0k,3880
20
- tinybird/tb/__cli__.py,sha256=1Q1Mk8PoldzfuJEf_f-VHn7VSe0wfdgeKCPK_RcPvag,247
20
+ tinybird/tb/__cli__.py,sha256=24_fIgbVB3P7UF7JqFvY_zPB1-ZShXJhWbhwh4ZB7Jk,247
21
21
  tinybird/tb/check_pypi.py,sha256=Gp0HkHHDFMSDL6nxKlOY51z7z1Uv-2LRexNTZSHHGmM,552
22
22
  tinybird/tb/cli.py,sha256=FdDFEIayjmsZEVsVSSvRiVYn_FHOVg_zWQzchnzfWho,1008
23
- tinybird/tb/client.py,sha256=pJbdkWMXGAqKseNAvdsRRnl_c7I-DCMB0dWCQnG82nU,54146
23
+ tinybird/tb/client.py,sha256=OVNlCXI16kpD-Ph8BDhkyKbR68TdZcR_j4ng91Iiybg,54706
24
24
  tinybird/tb/config.py,sha256=mhMTGnMB5KcxGoh3dewIr2Jjsa6pHE183gCPAQWyp6o,3973
25
25
  tinybird/tb/modules/build.py,sha256=efD-vamK1NPaDo9R86Hn8be2DYoW0Hh5bZiH7knK5dk,7790
26
26
  tinybird/tb/modules/build_common.py,sha256=dthlaDn_CuwZnedQcUi7iIdDoHWfSbbbGQwiDgNcmC0,13062
@@ -49,7 +49,7 @@ tinybird/tb/modules/local_common.py,sha256=_WODjW3oPshgsZ1jDFFx2nr0zrLi3Gxz5dlah
49
49
  tinybird/tb/modules/login.py,sha256=zerXZqIv15pbFk5XRt746xGcVnp01YmL_403byBf4jQ,1245
50
50
  tinybird/tb/modules/login_common.py,sha256=IfthYbHmC7EtsCXCB1iF4TngPOwfaHJ6Dfi_t7oBXnI,11640
51
51
  tinybird/tb/modules/logout.py,sha256=sniI4JNxpTrVeRCp0oGJuQ3yRerG4hH5uz6oBmjv724,1009
52
- tinybird/tb/modules/materialization.py,sha256=0O2JUCxLzz-DrXTUewVHlIyC6-Kyymw0hGXXDicMSHE,5403
52
+ tinybird/tb/modules/materialization.py,sha256=8fdbTTxFSk0Sjet3pcEk_x-cs4RGpgl6toN8vrMLXJE,5630
53
53
  tinybird/tb/modules/mock.py,sha256=ET8sRpmXnQsd2sSJXH_KCdREU1_XQgkORru6T357Akc,3260
54
54
  tinybird/tb/modules/mock_common.py,sha256=72yKp--Zo40hrycUtiajSRW2BojOsgOZFqUorQ_KQ3w,2279
55
55
  tinybird/tb/modules/open.py,sha256=LYiuO8Z1I9O_v6pv58qpUCWFD6BT00BdeO21fRa4I4Y,1315
@@ -64,20 +64,20 @@ tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,
64
64
  tinybird/tb/modules/telemetry.py,sha256=T9gtsQffWqG_4hRBaUJPzOfMkPwz7mH-R6Bn1XRYViA,11482
65
65
  tinybird/tb/modules/test.py,sha256=O2-mS4uMU6nPi7yWPpWzshAgOlYKiGS-tkM12pXQGMI,1906
66
66
  tinybird/tb/modules/test_common.py,sha256=YZwAdSfYVXdvArfTc9tH-2QBOhb_XbnJ3eKvyXTJuEM,12717
67
- tinybird/tb/modules/token.py,sha256=DkXW9FNCLGBisXewfk195jTJ6B1Iz7zq3cEEac48aAs,12731
67
+ tinybird/tb/modules/token.py,sha256=ZhW_o7XCr90wJRhMN6816vyo_TVfnzPXyIhrhzQ7oZ0,13807
68
68
  tinybird/tb/modules/watch.py,sha256=No0bK1M1_3CYuMaIgylxf7vYFJ72lTJe3brz6xQ-mJo,8819
69
69
  tinybird/tb/modules/workspace.py,sha256=Q_8HcxMsNg8QG9aBlwcWS2umrDP5IkTIHqqz3sfmGuc,11341
70
70
  tinybird/tb/modules/workspace_members.py,sha256=5JdkJgfuEwbq-t6vxkBhYwgsiTDxF790wsa6Xfif9nk,8608
71
71
  tinybird/tb/modules/agent/__init__.py,sha256=i3oe3vDIWWPaicdCM0zs7D7BJ1W0k7th93ooskHAV00,54
72
- tinybird/tb/modules/agent/agent.py,sha256=cHpPZiUeW525i9PxspGoilTc-1HPAHCCzxiYdcdJQ7c,28214
72
+ tinybird/tb/modules/agent/agent.py,sha256=aDMjkZUZVTW39HjsusBJkzc4TSVrD_clAQK2V-IJtE0,29020
73
73
  tinybird/tb/modules/agent/animations.py,sha256=4WOC5_2BracttmMCrV0H91tXfWcUzQHBUaIJc5FA7tE,3490
74
- tinybird/tb/modules/agent/banner.py,sha256=2UpuuIqWxS0Ltab6i_FE4dkNxlJCdgKGCMtbwQGiLA8,7185
74
+ tinybird/tb/modules/agent/banner.py,sha256=IM7UtRqSoC6xFJ-TU33-1HrV6I2KVYQsVMeI4GgJsb0,6045
75
75
  tinybird/tb/modules/agent/command_agent.py,sha256=Q4M5qV9j3aETrXswoWZ02ZWQZhJm42HGHO1ymJrfDnw,2665
76
76
  tinybird/tb/modules/agent/memory.py,sha256=O6Kumn9AyKxcTkhI45yjAUZ3ZIAibLOcNWoiEuLYeqY,3245
77
- tinybird/tb/modules/agent/models.py,sha256=LW1D27gjcd_jwFmghEzteCgToDfodX2B6B5S8BYbysw,735
77
+ tinybird/tb/modules/agent/models.py,sha256=IAxqlnHy8c2OeSnDrrSp2Mg38W9_r0GsDM87Wv-YNfM,925
78
78
  tinybird/tb/modules/agent/prompts.py,sha256=NEIk3OK0xXm3QS1Iox4T1MMo19hLhfaICMEwzqVGW7E,31069
79
79
  tinybird/tb/modules/agent/testing_agent.py,sha256=mH7ccuWeTnkpENCmwym9ubDFncMXQoSo0jq2pRxJVDY,2553
80
- tinybird/tb/modules/agent/utils.py,sha256=VYuoodb05Ucq0b3qgIAf2KhOTTRD85_Pfab0xKwbg40,29610
80
+ tinybird/tb/modules/agent/utils.py,sha256=Tv9NwPYPwkdWMfxfrDolVVglrBWnMUViQFE2nxaQMdg,29613
81
81
  tinybird/tb/modules/agent/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  tinybird/tb/modules/agent/tools/analyze.py,sha256=CR5LXg4fou-zYEksqnjpJ0icvxJVoKnTctoI1NRvqCM,3873
83
83
  tinybird/tb/modules/agent/tools/append.py,sha256=XA8ZeqxZcRL_0ZCd5FyggpWeH53mwTMby4lHV8wQa7c,6039
@@ -116,8 +116,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
116
116
  tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
117
117
  tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
118
118
  tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
119
- tinybird-0.0.1.dev264.dist-info/METADATA,sha256=PCl2AWV403ysmvj35_eYngYE_1wfUNqlUlBN5mxep5M,1733
120
- tinybird-0.0.1.dev264.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
121
- tinybird-0.0.1.dev264.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
122
- tinybird-0.0.1.dev264.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
123
- tinybird-0.0.1.dev264.dist-info/RECORD,,
119
+ tinybird-0.0.1.dev266.dist-info/METADATA,sha256=GCalRxwS9i9RPYR0zmKe-vYpxFoMzjG7JoiUmWzv4aY,1733
120
+ tinybird-0.0.1.dev266.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
121
+ tinybird-0.0.1.dev266.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
122
+ tinybird-0.0.1.dev266.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
123
+ tinybird-0.0.1.dev266.dist-info/RECORD,,