tinybird 0.0.1.dev301__py3-none-any.whl → 0.0.1.dev303__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.dev301'
8
- __revision__ = '1ce40fd'
7
+ __version__ = '0.0.1.dev303'
8
+ __revision__ = 'ff545f6'
@@ -6,7 +6,6 @@ import sys
6
6
  import urllib.parse
7
7
  import uuid
8
8
  from functools import partial
9
- from pathlib import Path
10
9
  from typing import Any, Callable, Optional
11
10
 
12
11
  import click
@@ -27,7 +26,6 @@ from tinybird.tb.modules.agent.file_agent import FileAgent
27
26
  from tinybird.tb.modules.agent.memory import (
28
27
  clear_history,
29
28
  clear_messages,
30
- get_last_messages_from_last_user_prompt,
31
29
  save_messages,
32
30
  )
33
31
  from tinybird.tb.modules.agent.mock_agent import MockAgent
@@ -72,12 +70,12 @@ from tinybird.tb.modules.common import (
72
70
  )
73
71
  from tinybird.tb.modules.config import CLIConfig
74
72
  from tinybird.tb.modules.deployment_common import create_deployment
75
- from tinybird.tb.modules.exceptions import CLIBuildException, CLIDeploymentException, CLIMockException
73
+ from tinybird.tb.modules.exceptions import CLIBuildException, CLIDeploymentException
76
74
  from tinybird.tb.modules.feedback_manager import FeedbackManager
77
75
  from tinybird.tb.modules.llm import LLM
78
76
  from tinybird.tb.modules.local_common import get_tinybird_local_client
79
77
  from tinybird.tb.modules.login_common import login
80
- from tinybird.tb.modules.mock_common import append_mock_data, create_mock_data
78
+ from tinybird.tb.modules.mock_common import append_mock_data
81
79
  from tinybird.tb.modules.project import Project
82
80
  from tinybird.tb.modules.test_common import run_tests as run_tests_common
83
81
 
@@ -92,6 +90,7 @@ class TinybirdAgent:
92
90
  project: Project,
93
91
  dangerously_skip_permissions: bool,
94
92
  prompt_mode: bool,
93
+ feature: Optional[str] = None,
95
94
  ):
96
95
  self.token = token
97
96
  self.user_token = user_token
@@ -101,14 +100,12 @@ class TinybirdAgent:
101
100
  self.project = project
102
101
  self.thinking_animation = ThinkingAnimation()
103
102
  self.confirmed_plan_id: Optional[str] = None
104
- if prompt_mode:
105
- self.messages: list[ModelMessage] = get_last_messages_from_last_user_prompt()
106
- else:
107
- self.messages = []
103
+ self.feature = feature
104
+ self.messages: list[ModelMessage] = []
108
105
  cli_config = CLIConfig.get_project_config()
109
106
  regions = get_regions(cli_config)
110
107
  self.agent = Agent(
111
- model=create_model(user_token, host, workspace_id),
108
+ model=create_model(user_token, host, workspace_id, feature=feature),
112
109
  deps_type=TinybirdAgentContext,
113
110
  instructions=[agent_system_prompt],
114
111
  tools=[
@@ -382,7 +379,6 @@ class TinybirdAgent:
382
379
  build_project=partial(build_project, project=project, config=config),
383
380
  deploy_project=partial(deploy_project, project=project, config=config),
384
381
  deploy_check_project=partial(deploy_check_project, project=project, config=config),
385
- mock_data=partial(mock_data, project=project, config=config),
386
382
  append_data_local=partial(append_data_local, config=config),
387
383
  append_data_cloud=partial(append_data_cloud, config=config),
388
384
  analyze_fixture=partial(analyze_fixture, config=config),
@@ -511,7 +507,11 @@ class TinybirdAgent:
511
507
 
512
508
 
513
509
  def run_agent(
514
- config: dict[str, Any], project: Project, dangerously_skip_permissions: bool, prompt: Optional[str] = None
510
+ config: dict[str, Any],
511
+ project: Project,
512
+ dangerously_skip_permissions: bool,
513
+ prompt: Optional[str] = None,
514
+ feature: Optional[str] = None,
515
515
  ):
516
516
  if not prompt:
517
517
  latest_version = CheckPypi().get_latest_version()
@@ -526,7 +526,10 @@ def run_agent(
526
526
  )
527
527
  if yes:
528
528
  update_cli()
529
- click.echo(FeedbackManager.highlight(message="» Initializing Tinybird Code..."))
529
+
530
+ if not prompt:
531
+ click.echo(FeedbackManager.highlight(message="» Initializing Tinybird Code..."))
532
+
530
533
  token = config.get("token", "")
531
534
  host = config.get("host", "")
532
535
  user_token = config.get("user_token", "")
@@ -585,6 +588,7 @@ def run_agent(
585
588
  project,
586
589
  dangerously_skip_permissions,
587
590
  prompt_mode,
591
+ feature,
588
592
  )
589
593
 
590
594
  # Print mode: run once with the provided prompt and exit
@@ -763,36 +767,6 @@ def append_data_cloud(config: dict[str, Any], datasource_name: str, path: str) -
763
767
  append_mock_data(client, datasource_name, path)
764
768
 
765
769
 
766
- def mock_data(
767
- config: dict[str, Any],
768
- project: Project,
769
- datasource_name: str,
770
- data_format: str,
771
- rows: int,
772
- context: Optional[str] = None,
773
- ) -> list[dict[str, Any]]:
774
- client = get_tinybird_local_client(config, test=False, silent=False)
775
- cli_config = CLIConfig.get_project_config()
776
- datasource_path = project.get_resource_path(datasource_name, "datasource")
777
-
778
- if not datasource_path:
779
- raise CLIMockException(f"Datasource {datasource_name} not found")
780
-
781
- datasource_content = Path(datasource_path).read_text()
782
- return create_mock_data(
783
- datasource_name,
784
- datasource_content,
785
- rows,
786
- context or "",
787
- cli_config,
788
- config,
789
- cli_config.get_user_token() or "",
790
- client,
791
- data_format,
792
- project.folder,
793
- )
794
-
795
-
796
770
  def analyze_fixture(config: dict[str, Any], fixture_path: str, format: str = "json") -> dict[str, Any]:
797
771
  local_client = get_tinybird_local_client(config, test=False, silent=True)
798
772
  meta, _data = _analyze(fixture_path, local_client, format)
@@ -84,4 +84,4 @@ def display_banner():
84
84
  colored_line += f"{color_code}{char}"
85
85
 
86
86
  click.echo(colored_line + reset)
87
- click.echo()
87
+ click.echo("")
@@ -8,7 +8,7 @@ from pydantic_ai.retries import AsyncTenacityTransport, wait_retry_after
8
8
  from tenacity import AsyncRetrying, retry_if_exception_type, stop_after_attempt, wait_exponential
9
9
 
10
10
 
11
- def create_retrying_client(token: str, workspace_id: str):
11
+ def create_retrying_client(token: str, workspace_id: str, feature: Optional[str] = None):
12
12
  """Create a client with smart retry handling for multiple error types."""
13
13
 
14
14
  def should_retry_status(response):
@@ -29,7 +29,10 @@ def create_retrying_client(token: str, workspace_id: str):
29
29
  ),
30
30
  validate_response=should_retry_status,
31
31
  )
32
- return AsyncClient(transport=transport, params={"token": token, "workspace_id": workspace_id})
32
+ params = {"token": token, "workspace_id": workspace_id}
33
+ if feature:
34
+ params["feature"] = feature
35
+ return AsyncClient(transport=transport, params=params)
33
36
 
34
37
 
35
38
  def create_model(
@@ -38,6 +41,7 @@ def create_model(
38
41
  workspace_id: str,
39
42
  model: AnthropicModelName = "claude-4-sonnet-20250514",
40
43
  run_id: Optional[str] = None,
44
+ feature: Optional[str] = None,
41
45
  ):
42
46
  default_headers = {}
43
47
  if run_id:
@@ -24,7 +24,7 @@ def deploy(ctx: RunContext[TinybirdAgentContext], allow_destructive_operations:
24
24
  FeedbackManager.warning(message="Destructive operations flag is enabled due to a file deleted recently")
25
25
  )
26
26
 
27
- click.echo()
27
+ click.echo("")
28
28
  confirmation = show_confirmation(
29
29
  title="Deploy the project?",
30
30
  skip_confirmation=False,
@@ -121,7 +121,7 @@ def execute_query(
121
121
  bytes_read = humanfriendly.format_size(stats["bytes_read"])
122
122
 
123
123
  click.echo(FeedbackManager.info_query_stats(seconds=seconds, rows=rows_read, bytes=bytes_read))
124
- click.echo()
124
+ click.echo("")
125
125
 
126
126
  if not result["data"]:
127
127
  click.echo(FeedbackManager.info_no_rows())
@@ -44,7 +44,6 @@ class TinybirdAgentContext(BaseModel):
44
44
  build_project_test: Callable[..., None]
45
45
  deploy_project: Callable[..., None]
46
46
  deploy_check_project: Callable[[], None]
47
- mock_data: Callable[..., list[dict[str, Any]]]
48
47
  append_data_local: Callable[..., None]
49
48
  append_data_cloud: Callable[..., None]
50
49
  analyze_fixture: Callable[..., dict[str, Any]]
@@ -488,7 +488,6 @@ def create_ctx_client(
488
488
  "logout",
489
489
  "update",
490
490
  "upgrade",
491
- "create",
492
491
  "info",
493
492
  "tag",
494
493
  "push",
@@ -502,7 +501,7 @@ def create_ctx_client(
502
501
  return None
503
502
 
504
503
  commands_always_cloud = ["infra"]
505
- commands_always_local = ["build", "dev"]
504
+ commands_always_local = ["build", "dev", "create"]
506
505
  command_always_test = ["test"]
507
506
 
508
507
  if (
@@ -3,25 +3,22 @@ import os
3
3
  import re
4
4
  import shutil
5
5
  from pathlib import Path
6
- from typing import Any, Dict, List, Optional
6
+ from typing import Any, Dict, List, Optional, Set
7
7
  from urllib.parse import urlparse
8
8
 
9
9
  import click
10
10
  import requests
11
11
 
12
- from tinybird.prompts import claude_rules_prompt, create_prompt, readme_prompt, rules_prompt
13
- from tinybird.tb.client import TinyB
12
+ from tinybird.prompts import claude_rules_prompt, rules_prompt
13
+ from tinybird.tb.modules.agent import run_agent
14
14
  from tinybird.tb.modules.cicd import init_cicd
15
15
  from tinybird.tb.modules.cli import cli
16
- from tinybird.tb.modules.common import _generate_datafile, generate_datafile
16
+ from tinybird.tb.modules.common import _generate_datafile
17
17
  from tinybird.tb.modules.config import CLIConfig
18
18
  from tinybird.tb.modules.datafile.fixture import persist_fixture
19
19
  from tinybird.tb.modules.exceptions import CLICreateException
20
20
  from tinybird.tb.modules.feedback_manager import FeedbackManager
21
- from tinybird.tb.modules.llm import LLM
22
- from tinybird.tb.modules.llm_utils import extract_xml, parse_xml
23
21
  from tinybird.tb.modules.local_common import get_tinybird_local_client
24
- from tinybird.tb.modules.mock_common import create_mock_data
25
22
  from tinybird.tb.modules.project import Project
26
23
 
27
24
 
@@ -67,13 +64,9 @@ def create(
67
64
  folder_path.mkdir()
68
65
 
69
66
  try:
70
- tb_client = config.get_client(token=ctx_config.get("token"), host=ctx_config.get("host"))
71
- user_token: str = ""
72
67
  created_something = False
73
- if prompt:
74
- user_token = ctx_config.get("user_token")
75
- if not user_token:
76
- raise Exception("This action requires authentication. Run 'tb login' first.")
68
+ if prompt and not ctx_config.get("user_token"):
69
+ raise Exception("This action requires authentication. Run 'tb login' first.")
77
70
 
78
71
  if not validate_project_structure(project):
79
72
  click.echo(FeedbackManager.highlight(message="\n» Creating new project structure..."))
@@ -99,28 +92,20 @@ def create(
99
92
 
100
93
  prompt_result: List[Path] = []
101
94
  if prompt:
102
- prompt_result = create_resources_from_prompt(tb_client, user_token, prompt, project)
103
- result.extend(prompt_result)
104
- readme_path = folder_path / "README.md"
105
- if readme_path.exists():
106
- click.echo(FeedbackManager.highlight(message="\n» Updating project description..."))
107
- else:
108
- click.echo(FeedbackManager.highlight(message="\n» Creating project description..."))
109
- readme_path.touch()
110
- llm = LLM(user_token=str(user_token), host=tb_client.host)
111
- readme_user_prompt = prompt or ""
112
- all_resources_xml = get_resources_xml(project)
113
- readme_response = llm.ask(
114
- system_prompt=readme_prompt(
115
- readme_path.read_text(), tb_client.host, "$TB_ADMIN_TOKEN", all_resources_xml
116
- ),
117
- prompt=readme_user_prompt,
118
- feature="tb_create_readme",
95
+ prompt_instructions = (
96
+ "Create or update the Tinybird datasources, pipes, and connections required to satisfy the following request. "
97
+ "Do not generate mock data or append data; those steps will run later programmatically."
119
98
  )
120
- readme_result = extract_xml(readme_response, "readme")
121
- readme_path.write_text(readme_result)
122
- click.echo(FeedbackManager.info_file_created(file="README.md"))
123
- created_something = True
99
+ prompt_result = create_resources_from_prompt(
100
+ ctx_config,
101
+ project,
102
+ prompt,
103
+ feature="tb_create",
104
+ instructions=prompt_instructions,
105
+ )
106
+ result.extend(prompt_result)
107
+ if prompt_result:
108
+ created_something = True
124
109
 
125
110
  if data or prompt:
126
111
  click.echo(FeedbackManager.success(message="✓ Resources created!\n"))
@@ -180,24 +165,30 @@ def create(
180
165
  datasource_name = datasource_path.stem
181
166
  datasource_content = datasource_path.read_text()
182
167
  has_json_path = "`json:" in datasource_content
183
- if has_json_path:
184
- mock_data = create_mock_data(
185
- datasource_name,
186
- datasource_content,
187
- rows,
188
- prompt,
189
- config,
190
- ctx_config,
191
- user_token,
192
- tb_client,
193
- format_="ndjson",
194
- folder=project.folder,
195
- )
196
- if mock_data:
197
- persist_fixture(datasource_name, mock_data, folder, format="ndjson")
198
- click.echo(FeedbackManager.info_file_created(file=f"fixtures/{datasource_name}.ndjson"))
199
- click.echo(FeedbackManager.success(message="✓ Done!"))
200
- created_something = True
168
+ if not has_json_path:
169
+ continue
170
+
171
+ fixture_path = Path(folder) / "fixtures" / f"{datasource_name}.ndjson"
172
+ fixture_existed = fixture_path.exists()
173
+ fixture_prompt = (
174
+ f"Generate {rows} rows of representative sample data for the Tinybird datasource defined in {datasource_path}. "
175
+ f"Store the data in ndjson format at fixtures/{datasource_name}.ndjson."
176
+ )
177
+ if prompt.strip():
178
+ fixture_prompt += f"\n\nOriginal project request:\n{prompt.strip()}"
179
+
180
+ run_agent(
181
+ ctx_config,
182
+ project,
183
+ True,
184
+ prompt=fixture_prompt,
185
+ feature="tb_mock",
186
+ )
187
+
188
+ if fixture_path.exists() and not fixture_existed:
189
+ click.echo(FeedbackManager.info_file_created(file=f"fixtures/{datasource_name}.ndjson"))
190
+ click.echo(FeedbackManager.success(message="✓ Done!"))
191
+ created_something = True
201
192
 
202
193
  if not created_something and not len(result) > 0:
203
194
  click.echo(FeedbackManager.warning(message="△ No resources created\n"))
@@ -291,86 +282,39 @@ def create_project_structure(folder: str):
291
282
 
292
283
 
293
284
  def create_resources_from_prompt(
294
- tb_client: TinyB,
295
- user_token: str,
296
- prompt: str,
285
+ config: Dict[str, Any],
297
286
  project: Project,
298
- feature: str = "tb_create_resources",
287
+ prompt: str,
288
+ feature: str = "tb_create",
289
+ instructions: Optional[str] = None,
299
290
  ) -> List[Path]:
300
- result: List[Path] = []
301
- datasource_paths = [Path(ds_file) for ds_file in project.get_datasource_files()]
302
- pipes_paths = [Path(pipe_file) for pipe_file in project.get_pipe_files()]
303
- connections_paths = [Path(conn_file) for conn_file in project.get_connection_files()]
304
- resources_xml = "\n".join(
305
- [
306
- f"<resource><type>{resource_type}</type><name>{resource_name}</name><content>{resource_content}</content></resource>"
307
- for resource_type, resource_name, resource_content in [
308
- ("datasource", ds.stem, ds.read_text()) for ds in datasource_paths
309
- ]
310
- + [
311
- (
312
- "pipe",
313
- pipe.stem,
314
- pipe.read_text(),
315
- )
316
- for pipe in pipes_paths
317
- ]
318
- + [
319
- (
320
- "connection",
321
- conn.stem,
322
- conn.read_text(),
323
- )
324
- for conn in connections_paths
325
- ]
326
- ]
327
- )
328
- llm = LLM(user_token=user_token, host=tb_client.host)
329
- prompt_result = llm.ask(system_prompt=create_prompt(resources_xml), prompt=prompt, feature=feature)
330
- prompt_result = extract_xml(prompt_result, "response")
331
- resources = parse_xml(prompt_result, "resource")
332
- datasources = []
333
- pipes = []
334
- connections = []
335
- for resource_xml in resources:
336
- resource_type = extract_xml(resource_xml, "type")
337
- name = extract_xml(resource_xml, "name")
338
- content = extract_xml(resource_xml, "content")
339
- resource = {
340
- "name": name,
341
- "content": content,
342
- }
343
- if resource_type.lower() == "datasource":
344
- datasources.append(resource)
345
- elif resource_type.lower() == "pipe":
346
- pipes.append(resource)
347
- elif resource_type.lower() == "connection":
348
- connections.append(resource)
349
-
350
- for ds in datasources:
351
- content = ds["content"].replace("```", "")
352
- filename = f"{ds['name']}.datasource"
353
- ds_file = generate_datafile(
354
- content,
355
- filename=filename,
356
- data=None,
357
- _format="ndjson",
358
- force=True,
359
- folder=project.folder,
360
- )
361
- result.append(ds_file)
362
- for pipe in pipes:
363
- content = pipe["content"].replace("```", "")
364
- pipe_file = generate_pipe_file(pipe["name"], content, project.folder)
365
- result.append(pipe_file)
291
+ """Run the agent in prompt mode and report newly created project resources."""
366
292
 
367
- for conn in connections:
368
- content = conn["content"].replace("```", "")
369
- filename = f"{conn['name']}.connection"
370
- conn_file = generate_connection_file(conn["name"], content, project.folder)
371
- result.append(conn_file)
293
+ agent_prompt = prompt.strip()
294
+ if instructions:
295
+ instructions = instructions.strip()
296
+ if agent_prompt:
297
+ agent_prompt = f"{instructions}\n\n{agent_prompt}"
298
+ else:
299
+ agent_prompt = instructions
372
300
 
373
- return result
301
+ if not agent_prompt:
302
+ return []
303
+
304
+ resources_before = _collect_project_resource_paths(project)
305
+ run_agent(config, project, True, prompt=agent_prompt, feature=feature)
306
+ resources_after = _collect_project_resource_paths(project)
307
+
308
+ created_resources = [Path(path) for path in sorted(resources_after - resources_before)]
309
+ return created_resources
310
+
311
+
312
+ def _collect_project_resource_paths(project: Project) -> Set[Path]:
313
+ resources: Set[Path] = set()
314
+ resources.update(Path(path) for path in project.get_datasource_files())
315
+ resources.update(Path(path) for path in project.get_pipe_files())
316
+ resources.update(Path(path) for path in project.get_connection_files())
317
+ return resources
374
318
 
375
319
 
376
320
  def init_git(folder: str):
@@ -513,28 +457,6 @@ def save_context(prompt: str, feedback: str):
513
457
  context_file.write_text(f"- {prompt}\n{feedback}")
514
458
 
515
459
 
516
- def get_resources_xml(project: Project) -> str:
517
- datasource_paths = [Path(f) for f in project.get_datasource_files()]
518
- pipes_paths = [Path(f) for f in project.get_pipe_files()]
519
- resources_xml = "\n".join(
520
- [
521
- f"<resource><type>{resource_type}</type><name>{resource_name}</name><content>{resource_content}</content></resource>"
522
- for resource_type, resource_name, resource_content in [
523
- ("datasource", ds.stem, ds.read_text()) for ds in datasource_paths
524
- ]
525
- + [
526
- (
527
- "pipe",
528
- pipe.stem,
529
- pipe.read_text(),
530
- )
531
- for pipe in pipes_paths
532
- ]
533
- ]
534
- )
535
- return resources_xml
536
-
537
-
538
460
  def create_resources_from_data(
539
461
  data: str,
540
462
  project: Project,
@@ -768,13 +768,31 @@ def datasource_create(
768
768
 
769
769
  if datasource_type == "prompt":
770
770
  click.echo(FeedbackManager.gray(message="\n» Creating .datasource file..."))
771
- user_token = config.get("user_token")
772
- if not user_token:
771
+ if not config.get("user_token"):
773
772
  raise Exception("This action requires authentication. Run 'tb login' first.")
774
- project_config = CLIConfig.get_project_config()
775
- tb_client: TinyB = project_config.get_client(token=config.get("token"), host=config.get("host"))
776
- create_resources_from_prompt(tb_client, user_token, prompt, project, feature="tb_datasource_create")
777
- click.echo(FeedbackManager.success(message=" .datasource created!"))
773
+
774
+ instructions = (
775
+ "Create or update a Tinybird datasource (.datasource file) for this project. "
776
+ "Do not generate mock data or append data; those steps will run later programmatically."
777
+ )
778
+ if name:
779
+ instructions += f" Name the datasource '{name}'."
780
+
781
+ created_resources = create_resources_from_prompt(
782
+ config,
783
+ project,
784
+ prompt,
785
+ feature="tb_datasource_create",
786
+ instructions=instructions,
787
+ )
788
+ if any(path.suffix == ".datasource" for path in created_resources):
789
+ click.echo(FeedbackManager.success(message="✓ .datasource created!"))
790
+ else:
791
+ click.echo(
792
+ FeedbackManager.gray(
793
+ message="△ No new datasource file detected. Existing resources may have been updated instead."
794
+ )
795
+ )
778
796
  return
779
797
 
780
798
  connection_required = datasource_type in ("kafka", "s3", "gcs")
@@ -1,15 +1,9 @@
1
- import glob
2
- from pathlib import Path
3
-
4
1
  import click
5
2
 
6
- from tinybird.tb.client import TinyB
3
+ from tinybird.tb.modules.agent import run_agent
7
4
  from tinybird.tb.modules.cli import cli
8
- from tinybird.tb.modules.config import CLIConfig
9
- from tinybird.tb.modules.datafile.fixture import persist_fixture
10
5
  from tinybird.tb.modules.exceptions import CLIMockException
11
6
  from tinybird.tb.modules.feedback_manager import FeedbackManager
12
- from tinybird.tb.modules.mock_common import append_mock_data, create_mock_data
13
7
  from tinybird.tb.modules.project import Project
14
8
 
15
9
 
@@ -31,60 +25,17 @@ from tinybird.tb.modules.project import Project
31
25
  )
32
26
  @click.pass_context
33
27
  def mock(ctx: click.Context, datasource: str, rows: int, prompt: str, format_: str) -> None:
34
- """Generate sample data for a data source.
35
-
36
- Args:
37
- datasource: Path to the datasource file to load sample data into
38
- rows: Number of events to send
39
- prompt: Extra context to use for data generation
40
- skip: Skip following up on the generated data
41
- """
28
+ """Generate sample data for a data source."""
42
29
 
43
30
  try:
44
- tb_client: TinyB = ctx.ensure_object(dict)["client"]
45
31
  project: Project = ctx.ensure_object(dict)["project"]
46
32
  ctx_config = ctx.ensure_object(dict)["config"]
33
+ prompt = f"""Generate mock data for the following datasource: {datasource} with {rows} rows and {format_} format. Extra context: {prompt}"""
47
34
  env = ctx.ensure_object(dict)["env"]
48
- datasource_path = Path(datasource)
49
- datasource_name = datasource
50
- folder = project.folder
51
- click.echo(FeedbackManager.highlight(message=f"\n» Creating fixture for {datasource_name}..."))
52
- if datasource_path.suffix == ".datasource":
53
- datasource_name = datasource_path.stem
54
- else:
55
- datasource_from_glob = glob.glob(f"{folder}/**/{datasource}.datasource")
56
- if datasource_from_glob:
57
- datasource_path = Path(datasource_from_glob[0])
58
-
59
- if not datasource_path.exists():
60
- raise Exception(f"Datasource '{datasource_path.stem}' not found")
61
-
62
- datasource_content = datasource_path.read_text()
63
- config = CLIConfig.get_project_config()
64
- user_token = ctx_config.get("user_token")
65
-
66
- if not user_token:
67
- raise Exception("This action requires authentication. Run 'tb login' first.")
68
-
69
- data = create_mock_data(
70
- datasource_name,
71
- datasource_content,
72
- rows,
73
- prompt,
74
- config,
75
- ctx_config,
76
- user_token,
77
- tb_client,
78
- format_,
79
- folder,
80
- )
81
-
82
- fixture_path = persist_fixture(datasource_name, data, folder, format=format_)
83
- click.echo(FeedbackManager.info(message=f"✓ /fixtures/{datasource_name}.{format_} created"))
84
35
  if env == "cloud":
85
- append_mock_data(tb_client, datasource_name, str(fixture_path))
36
+ prompt += "Append the fixture data to the datasource in Tinybird Cloud."
86
37
 
87
- click.echo(FeedbackManager.success(message=f"✓ Sample data for {datasource_name} created with {rows} rows"))
38
+ run_agent(ctx_config, project, True, prompt=prompt, feature="tb_mock")
88
39
 
89
40
  except Exception as e:
90
41
  raise CLIMockException(FeedbackManager.error(message=str(e)))
@@ -1,12 +1,5 @@
1
- from typing import Any, Dict, List
2
-
3
- from tinybird.prompts import mock_prompt
4
1
  from tinybird.tb.client import TinyB
5
2
  from tinybird.tb.modules.common import push_data
6
- from tinybird.tb.modules.config import CLIConfig
7
- from tinybird.tb.modules.datafile.fixture import persist_fixture_sql
8
- from tinybird.tb.modules.llm import LLM
9
- from tinybird.tb.modules.llm_utils import extract_xml
10
3
 
11
4
 
12
5
  def append_mock_data(
@@ -22,50 +15,3 @@ def append_mock_data(
22
15
  concurrency=1,
23
16
  silent=True,
24
17
  )
25
-
26
-
27
- def create_mock_data(
28
- datasource_name: str,
29
- datasource_content: str,
30
- rows: int,
31
- prompt: str,
32
- config: CLIConfig,
33
- ctx_config: Dict[str, Any],
34
- user_token: str,
35
- tb_client: TinyB,
36
- format_: str,
37
- folder: str,
38
- ) -> List[Dict[str, Any]]:
39
- user_client = config.get_client(token=ctx_config.get("token"), host=ctx_config.get("host"))
40
- llm = LLM(user_token=user_token, host=user_client.host)
41
- prompt = f"<datasource_schema>{datasource_content}</datasource_schema>\n<user_input>{prompt}</user_input>"
42
- sql = ""
43
- attempts = 0
44
- data = []
45
- error = ""
46
- sql_path = None
47
- while True:
48
- try:
49
- response = llm.ask(system_prompt=mock_prompt(rows, error), prompt=prompt, feature="tb_mock")
50
- sql = extract_xml(response, "sql")
51
- sql_path = persist_fixture_sql(datasource_name, sql, folder)
52
- sql_format = "JSON" if format_ == "ndjson" else "CSV"
53
- result = tb_client.query(f"SELECT * FROM ({sql}) LIMIT {rows} FORMAT {sql_format}")
54
- if sql_format == "JSON":
55
- data = result.get("data", [])[:rows]
56
- error_response = result.get("error", None)
57
- if error_response:
58
- raise Exception(error_response)
59
- else:
60
- data = result
61
- break
62
- except Exception as e:
63
- error = str(e)
64
- attempts += 1
65
- if attempts > 5:
66
- raise Exception(
67
- f"Failed to generate a valid solution. Check {str(sql_path or '.sql path')} and try again."
68
- )
69
- else:
70
- continue
71
- return data
@@ -8,9 +8,10 @@ from typing import Any, Tuple
8
8
  import click
9
9
 
10
10
  from tinybird.tb.client import TinyB
11
+ from tinybird.tb.modules.agent import run_agent
11
12
  from tinybird.tb.modules.cli import cli
12
13
  from tinybird.tb.modules.project import Project
13
- from tinybird.tb.modules.test_common import create_test, run_tests, update_test
14
+ from tinybird.tb.modules.test_common import run_tests, update_test
14
15
 
15
16
 
16
17
  @cli.group()
@@ -24,18 +25,18 @@ def test(ctx: click.Context) -> None:
24
25
  help="Create a test for an existing pipe",
25
26
  )
26
27
  @click.argument("name_or_filename", type=str)
27
- @click.option(
28
- "--prompt", type=str, default="Create a test for the selected pipe", help="Prompt to be used to create the test"
29
- )
28
+ @click.option("--prompt", type=str, default="", help="Prompt to be used to create the test")
30
29
  @click.pass_context
31
30
  def test_create(ctx: click.Context, name_or_filename: str, prompt: str) -> None:
32
31
  """
33
32
  Create a test for an existing pipe
34
33
  """
35
34
  project: Project = ctx.ensure_object(dict)["project"]
36
- client: TinyB = ctx.ensure_object(dict)["client"]
37
35
  config: dict[str, Any] = ctx.ensure_object(dict)["config"]
38
- create_test(name_or_filename, prompt, project, client, config=config)
36
+ prompt = (
37
+ f"""Create tests for the following pipe: {name_or_filename}. Extra context: {prompt or "No extra context."}"""
38
+ )
39
+ run_agent(config, project, True, prompt=prompt, feature="tb_test_create")
39
40
 
40
41
 
41
42
  @test.command(
@@ -14,14 +14,11 @@ import click
14
14
  import yaml
15
15
  from requests import Response
16
16
 
17
- from tinybird.prompts import test_create_prompt
18
17
  from tinybird.tb.client import TinyB
19
18
  from tinybird.tb.modules.build_common import process as build_project
20
19
  from tinybird.tb.modules.common import sys_exit
21
20
  from tinybird.tb.modules.exceptions import CLITestException
22
21
  from tinybird.tb.modules.feedback_manager import FeedbackManager
23
- from tinybird.tb.modules.llm import LLM
24
- from tinybird.tb.modules.llm_utils import extract_xml, parse_xml
25
22
  from tinybird.tb.modules.local_common import get_local_tokens, get_test_workspace_name
26
23
  from tinybird.tb.modules.project import Project
27
24
 
@@ -53,92 +50,6 @@ def generate_test_file(pipe_name: str, tests: List[Dict[str, Any]], folder: Opti
53
50
  return path
54
51
 
55
52
 
56
- def create_test(
57
- name_or_filename: str, prompt: str, project: Project, client: TinyB, config: dict[str, Any], preview: bool = False
58
- ) -> list[dict[str, Any]]:
59
- """
60
- Create a test for an existing pipe
61
- """
62
- tests: List[Dict[str, Any]] = []
63
-
64
- try:
65
- click.echo(FeedbackManager.highlight(message="\n» Building test environment"))
66
- build_error = build_project(
67
- project=project,
68
- tb_client=client,
69
- watch=False,
70
- silent=True,
71
- exit_on_error=False,
72
- config=config,
73
- load_fixtures=True,
74
- )
75
- if build_error:
76
- raise Exception(build_error)
77
- click.echo(FeedbackManager.info(message="✓ Done!\n"))
78
- folder = project.folder
79
- pipe_path = get_pipe_path(name_or_filename, folder)
80
- pipe_name = pipe_path.stem
81
- click.echo(FeedbackManager.highlight(message=f"» Creating tests for {pipe_name} endpoint..."))
82
- pipe_content = pipe_path.read_text()
83
- pipe = client._req(f"/v0/pipes/{pipe_name}")
84
- parameters = set([param["name"] for node in pipe["nodes"] for param in node["params"]])
85
-
86
- system_prompt = test_create_prompt.format(
87
- name=pipe_name,
88
- content=pipe_content,
89
- parameters=parameters or "No parameters",
90
- )
91
- user_token = config.get("user_token")
92
- if not user_token:
93
- raise Exception("No user token found")
94
-
95
- llm = LLM(user_token=user_token, host=config.get("host") or "")
96
- response_llm = llm.ask(system_prompt=system_prompt, prompt=prompt, feature="tb_test_create")
97
- response_xml = extract_xml(response_llm, "response")
98
- tests_content = parse_xml(response_xml, "test")
99
-
100
- for test_content in tests_content:
101
- test: Dict[str, Any] = {}
102
- test["name"] = extract_xml(test_content, "name")
103
- test["description"] = extract_xml(test_content, "description")
104
- parameters_api = extract_xml(test_content, "parameters")
105
- test["parameters"] = parameters_api.split("?")[1] if "?" in parameters_api else parameters_api
106
- test["expected_result"] = ""
107
-
108
- response = None
109
- try:
110
- response = get_pipe_data(client, pipe_name=pipe_name, test_params=test["parameters"])
111
- except Exception:
112
- pass
113
-
114
- if response:
115
- if response.status_code >= 400:
116
- test["expected_http_status"] = response.status_code
117
- test["expected_result"] = response.json()["error"]
118
- else:
119
- test.pop("expected_http_status", None)
120
- test["expected_result"] = response.text or ""
121
-
122
- tests.append(test)
123
-
124
- if not preview:
125
- if len(tests) > 0:
126
- generate_test_file(pipe_name, tests, folder, mode="a")
127
- for test in tests:
128
- test_name = test["name"]
129
- click.echo(FeedbackManager.info(message=f"✓ {test_name} created"))
130
- else:
131
- click.echo(FeedbackManager.info(message="* No tests created"))
132
-
133
- click.echo(FeedbackManager.success(message="✓ Done!\n"))
134
- except Exception as e:
135
- raise CLITestException(FeedbackManager.error(message=str(e)))
136
- finally:
137
- cleanup_test_workspace(client, project.folder)
138
-
139
- return tests
140
-
141
-
142
53
  def parse_tests(tests_content: str) -> List[Dict[str, Any]]:
143
54
  return yaml.safe_load(tests_content)
144
55
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybird
3
- Version: 0.0.1.dev301
3
+ Version: 0.0.1.dev303
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/forward/commands
6
6
  Author: Tinybird
@@ -18,7 +18,7 @@ tinybird/datafile/exceptions.py,sha256=8rw2umdZjtby85QbuRKFO5ETz_eRHwUY5l7eHsy1w
18
18
  tinybird/datafile/parse_connection.py,sha256=tRyn2Rpr1TeWet5BXmMoQgaotbGdYep1qiTak_OqC5E,1825
19
19
  tinybird/datafile/parse_datasource.py,sha256=ssW8QeFSgglVFi3sDZj_HgkJiTJ2069v2JgqnH3CkDE,1825
20
20
  tinybird/datafile/parse_pipe.py,sha256=8e9LMecSQVWHC4AXf8cdxoQ1nxUR4fTObYxTctO_EXQ,3816
21
- tinybird/tb/__cli__.py,sha256=O5MC9cmzrDP6k84cWTDY7avcJMRgZjYRkLdaV70DGbI,247
21
+ tinybird/tb/__cli__.py,sha256=JdjKIGe5U9dES4l14SZ9sE_kRHwzvS0kj4dvt70Px1Y,247
22
22
  tinybird/tb/check_pypi.py,sha256=Gp0HkHHDFMSDL6nxKlOY51z7z1Uv-2LRexNTZSHHGmM,552
23
23
  tinybird/tb/cli.py,sha256=FdDFEIayjmsZEVsVSSvRiVYn_FHOVg_zWQzchnzfWho,1008
24
24
  tinybird/tb/client.py,sha256=Z27O6kXbQ1ZVi_K6qzdUJoS877nt7rqQDRckOycjNmI,53544
@@ -26,13 +26,13 @@ tinybird/tb/config.py,sha256=XIKju3xxpo40oQ48zDtSv0vgUrBZBHSmHJi4SHksjXE,5447
26
26
  tinybird/tb/modules/build.py,sha256=q3f_CM-_yt7R24VCmQqe4yat1aPdLqmP_hW5WoqdxBg,7907
27
27
  tinybird/tb/modules/build_common.py,sha256=aBpumDCZ5FYfBErBa1zGbJMsxdInr68Z21K40W7-DLE,20151
28
28
  tinybird/tb/modules/cicd.py,sha256=0KLKccha9IP749QvlXBmzdWv1On3mFwMY4DUcJlBxiE,7326
29
- tinybird/tb/modules/cli.py,sha256=kPmGW71difgANCRVzKlbpAwGwldFRH-YryRBejM8ff4,20511
29
+ tinybird/tb/modules/cli.py,sha256=geWO5FRlpI9Xuv-sAjfnO-jFwCvaOZ49gAkEvwi-2aY,20503
30
30
  tinybird/tb/modules/common.py,sha256=1OwsFHjVPDAuxFctzGjXoqhbKzc_jb1HHq96RaPcaeU,83611
31
31
  tinybird/tb/modules/config.py,sha256=gK7rgaWTDd4ZKCrNEg_Uemr26EQjqWt6TjyQKujxOws,11462
32
32
  tinybird/tb/modules/connection.py,sha256=axp8Fny1_4PSLJGN4UF6WygyRbQtM3Lbt6thxHKTxzw,17790
33
33
  tinybird/tb/modules/copy.py,sha256=dPZkcIDvxjJrlQUIvToO0vsEEEs4EYumbNV77-BzNoU,4404
34
- tinybird/tb/modules/create.py,sha256=pJxHXG69c9Z_21s-7VuJ3RZOF_nJU51LEwiAkvI3dZY,23251
35
- tinybird/tb/modules/datasource.py,sha256=7Ugj62Nyj6eBB7v9Jyny44KenYSce7rVs2h09N_0hyE,41812
34
+ tinybird/tb/modules/create.py,sha256=j0WvO6LxuGW1ZOYVuvR1FxFls2oMmKePYNTRJMSXfuU,20135
35
+ tinybird/tb/modules/datasource.py,sha256=O-w4qwhAIitD_SLVdxkpknckliRp_xMswdB8n8Ohxo0,42335
36
36
  tinybird/tb/modules/deployment.py,sha256=v0layOmG0IMnuXc3RT39mpGfa5M8yPlrL9F089fJFCo,15964
37
37
  tinybird/tb/modules/deployment_common.py,sha256=ZX27oUw7u1ld20qiXH69j7m0DImOc5nckABZ37BPAn4,20406
38
38
  tinybird/tb/modules/deprecations.py,sha256=rrszC1f_JJeJ8mUxGoCxckQTJFBCR8wREf4XXXN-PRc,4507
@@ -51,8 +51,8 @@ tinybird/tb/modules/login.py,sha256=zerXZqIv15pbFk5XRt746xGcVnp01YmL_403byBf4jQ,
51
51
  tinybird/tb/modules/login_common.py,sha256=CKXD_BjivhGUmBtNbLTJwzQDr6885C72XPZjo0GLLvI,12010
52
52
  tinybird/tb/modules/logout.py,sha256=sniI4JNxpTrVeRCp0oGJuQ3yRerG4hH5uz6oBmjv724,1009
53
53
  tinybird/tb/modules/materialization.py,sha256=8fdbTTxFSk0Sjet3pcEk_x-cs4RGpgl6toN8vrMLXJE,5630
54
- tinybird/tb/modules/mock.py,sha256=ET8sRpmXnQsd2sSJXH_KCdREU1_XQgkORru6T357Akc,3260
55
- tinybird/tb/modules/mock_common.py,sha256=72yKp--Zo40hrycUtiajSRW2BojOsgOZFqUorQ_KQ3w,2279
54
+ tinybird/tb/modules/mock.py,sha256=zxSBvB_Bd3dhVnQUvZEhBREg0tqskzu5dQxF1YldOaw,1479
55
+ tinybird/tb/modules/mock_common.py,sha256=LaqBtbnjpMZBLMpVSwaWdKVCNA485-Gz_96ZfCqgvco,320
56
56
  tinybird/tb/modules/open.py,sha256=LYiuO8Z1I9O_v6pv58qpUCWFD6BT00BdeO21fRa4I4Y,1315
57
57
  tinybird/tb/modules/pipe.py,sha256=xPKtezhnWZ6k_g82r4XpgKslofhuIxb_PvynH4gdUzI,2393
58
58
  tinybird/tb/modules/project.py,sha256=tP6XuG8dR8QCA4pojlXZ7Am6EfS2h3Xnzw5lA3sdtlY,7747
@@ -63,35 +63,35 @@ tinybird/tb/modules/shell.py,sha256=ExOAY2SwywCc5D6X-WCbl7tAV73bYWcGAan4E6u02vI,
63
63
  tinybird/tb/modules/sink.py,sha256=dK2s__my0ePIUYrqBzhPSgdWN9rbpvP1G4dT7DJzz80,3865
64
64
  tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,11035
65
65
  tinybird/tb/modules/telemetry.py,sha256=T9gtsQffWqG_4hRBaUJPzOfMkPwz7mH-R6Bn1XRYViA,11482
66
- tinybird/tb/modules/test.py,sha256=gi7fH6zavFp1jDs3SoRWdf9uBiKjp1hdOPAEleg7H-Y,2145
67
- tinybird/tb/modules/test_common.py,sha256=501Fo6oDI-ZzJv8bqcLz7-6ulS8-FGViwi1tHq_A5h0,14766
66
+ tinybird/tb/modules/test.py,sha256=NcpRCEDA2itnGRrkao8UNYDZlJ4d35N55OfO_UyJR_U,2229
67
+ tinybird/tb/modules/test_common.py,sha256=7iaHMUSxWsXd98IRMkYezcTa-x1uNEUmG1T48wQenKk,11185
68
68
  tinybird/tb/modules/token.py,sha256=ZhW_o7XCr90wJRhMN6816vyo_TVfnzPXyIhrhzQ7oZ0,13807
69
69
  tinybird/tb/modules/watch.py,sha256=R0wERRyL-PrwxKOLSk-T-EvkIczHpeoGirrl3JZxXa8,8935
70
70
  tinybird/tb/modules/workspace.py,sha256=tCP1zZMwBhLRGm22TGfpSd4cHvQLAS1o_azIXv_r6uw,11172
71
71
  tinybird/tb/modules/workspace_members.py,sha256=5JdkJgfuEwbq-t6vxkBhYwgsiTDxF790wsa6Xfif9nk,8608
72
72
  tinybird/tb/modules/agent/__init__.py,sha256=i3oe3vDIWWPaicdCM0zs7D7BJ1W0k7th93ooskHAV00,54
73
- tinybird/tb/modules/agent/agent.py,sha256=R-njI3JNM5_qO5tdXatwV6KGDuyNa93Due9PKkPTShw,39988
73
+ tinybird/tb/modules/agent/agent.py,sha256=_PRCkFgpLCzo-5EdUphLKZ0pG8YMmBfCNFuHdTQKKO8,39057
74
74
  tinybird/tb/modules/agent/animations.py,sha256=4WOC5_2BracttmMCrV0H91tXfWcUzQHBUaIJc5FA7tE,3490
75
- tinybird/tb/modules/agent/banner.py,sha256=l6cO5Fi7lbVKp-GsBP8jf3IkjOWxg2jpAt9NBCy0WR8,4085
75
+ tinybird/tb/modules/agent/banner.py,sha256=1_TRj9Bmzcir_pKzoto6VCsMG9laWyT7RfDsUtKMrK0,4087
76
76
  tinybird/tb/modules/agent/command_agent.py,sha256=0Z08rQsir59zQAr-kkOvsKIFpIBsBSTGJJ1VgqqF5WA,3654
77
77
  tinybird/tb/modules/agent/compactor.py,sha256=BK5AxZFhrp3xWnsRnYaleiYoIWtVNc-_m650Hsopt8g,13841
78
78
  tinybird/tb/modules/agent/explore_agent.py,sha256=QVMPmX6GDW8bh65_X4yXepvAgJmNRQh1S-YwmvGHkjw,4288
79
79
  tinybird/tb/modules/agent/file_agent.py,sha256=vE8VChVbG_-uyeBtp3I6QrXeNaPaVlVoNn4c9cGTAJA,2466
80
80
  tinybird/tb/modules/agent/memory.py,sha256=vBewB_64L_wHoT4tLT6UX2uxcHwSY880QZ26F9rPqXs,3793
81
81
  tinybird/tb/modules/agent/mock_agent.py,sha256=9_w5-MJDC3vp0U5SkM-ucqhxftfpeUM4FPLl5BAr1_0,8200
82
- tinybird/tb/modules/agent/models.py,sha256=eokO8XlY-kVJOsbqiVporGUAOCyKAXCO5xgTEK9SM6Y,2208
82
+ tinybird/tb/modules/agent/models.py,sha256=QSTwxz_-U4_iQxXT_t3uJZRzZmIsuxVrdmV4APsr1ms,2346
83
83
  tinybird/tb/modules/agent/prompts.py,sha256=eua-QawthfG5X6Kz1dRzOZSjXU8tj0nr4k7onmvBZnk,45792
84
84
  tinybird/tb/modules/agent/testing_agent.py,sha256=AtwtJViH7805i7djyBgDb7SSUtDyJnw0TWJu6lBFsrg,2953
85
- tinybird/tb/modules/agent/utils.py,sha256=F4ZuaYPuDCHligFJT_265V8mKyPrsm591DTAzCAIMYk,31998
85
+ tinybird/tb/modules/agent/utils.py,sha256=KMSqOGLTOeyUxQfXES1maROMIKle2uz88z45sFAQXAs,31947
86
86
  tinybird/tb/modules/agent/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
87
  tinybird/tb/modules/agent/tools/analyze.py,sha256=CR5LXg4fou-zYEksqnjpJ0icvxJVoKnTctoI1NRvqCM,3873
88
88
  tinybird/tb/modules/agent/tools/append.py,sha256=cF-1XYmgTXI3dfMQ_nEpOKo6duJGe2GOg64rXNnS9gw,8284
89
89
  tinybird/tb/modules/agent/tools/build.py,sha256=Hm-xDAP9ckMiKquT-DmDg5H0yxZefLOaWKANyoVSaEQ,846
90
90
  tinybird/tb/modules/agent/tools/datafile.py,sha256=kTob7G2TwCwIgwom0rERgXQ13rgPtZv3_ByLnrvpIdU,10881
91
- tinybird/tb/modules/agent/tools/deploy.py,sha256=6Vmm0lCG8XKE2iUF_ZJrOqXbTFhoe3anPzYCFehQ3_E,2027
91
+ tinybird/tb/modules/agent/tools/deploy.py,sha256=uIth0nvkCrI-RXrADhWdWV0iGgdoSC-ej3DzJFzNkmk,2029
92
92
  tinybird/tb/modules/agent/tools/deploy_check.py,sha256=pE3d9TPtXVKZjYbU0G6ORAGI86lN5K_4JKUriClERbM,1229
93
93
  tinybird/tb/modules/agent/tools/diff_resource.py,sha256=_9xHcDzCTKk_E1wKQbuktVqV6U9sA0kqYaBxWvtliX0,2613
94
- tinybird/tb/modules/agent/tools/execute_query.py,sha256=DL2jsZ0jaEqFIkGoiWfR-IUAwsgoF0D-_JUhq7xe4gA,9145
94
+ tinybird/tb/modules/agent/tools/execute_query.py,sha256=ie3TUs1sYv_KK5kL-1hSn9wrPVZqr6q57yBv6fG-hOs,9147
95
95
  tinybird/tb/modules/agent/tools/file.py,sha256=_strhF1bnFFui3pVGUi2dFdcKzMyYzOD59lKeSHqG7o,2855
96
96
  tinybird/tb/modules/agent/tools/get_endpoint_stats.py,sha256=r2FrXg1L1s_Llr1tPdJ6k_gu6qw7qLsAXOkbz3eTk1g,2307
97
97
  tinybird/tb/modules/agent/tools/get_openapi_definition.py,sha256=4TIMO2XzHBMhpt9zIWRfjjPZbThT8r_iPS4CVHcItE0,2904
@@ -121,8 +121,8 @@ tinybird/tb_cli_modules/config.py,sha256=IsgdtFRnUrkY8-Zo32lmk6O7u3bHie1QCxLwgp4
121
121
  tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
122
122
  tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
123
123
  tinybird/tb_cli_modules/telemetry.py,sha256=Hh2Io8ZPROSunbOLuMvuIFU4TqwWPmQTqal4WS09K1A,10449
124
- tinybird-0.0.1.dev301.dist-info/METADATA,sha256=N4Ot_u5Ky4TsdsOj9LEFHpqY1i3VnaDBicMwZT306dA,1845
125
- tinybird-0.0.1.dev301.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
126
- tinybird-0.0.1.dev301.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
127
- tinybird-0.0.1.dev301.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
128
- tinybird-0.0.1.dev301.dist-info/RECORD,,
124
+ tinybird-0.0.1.dev303.dist-info/METADATA,sha256=pkCbWHaIqhFLkaXhGSJ1FoqUOeIJce4T0wxS7wXiRR0,1845
125
+ tinybird-0.0.1.dev303.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
126
+ tinybird-0.0.1.dev303.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
127
+ tinybird-0.0.1.dev303.dist-info/top_level.txt,sha256=VqqqEmkAy7UNaD8-V51FCoMMWXjLUlR0IstvK7tJYVY,54
128
+ tinybird-0.0.1.dev303.dist-info/RECORD,,