tinybird 0.0.1.dev35__py3-none-any.whl → 0.0.1.dev36__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/prompts.py CHANGED
@@ -641,6 +641,7 @@ The previous instructions are explanations of how things work in Tinybird. Answe
641
641
 
642
642
  datasource_instructions = """
643
643
  <datasource_file_instructions>
644
+ - Content cannot be empty.
644
645
  - The datasource names must be unique.
645
646
  - No indentation is allowed for property names: DESCRIPTION, SCHEMA, ENGINE, ENGINE_PARTITION_KEY, ENGINE_SORTING_KEY, etc.
646
647
  - Use MergeTree engine by default.
@@ -701,6 +702,7 @@ sql_instructions = """
701
702
  </valid_query_with_parameters_with_%_on_top>
702
703
  - The Parameter functions like this one {{{{String(my_param_name,default_value)}}}} can be one of the following: String, DateTime, Date, Float32, Float64, Int, Integer, UInt8, UInt16, UInt32, UInt64, UInt128, UInt256, Int8, Int16, Int32, Int64, Int128, Int256
703
704
  - Parameter names must be different from column names. Pass always the param name and a default value to the function.
705
+ - Use ALWAYS hardcoded values for default values for parameters.
704
706
  - Code inside the template {{{{template_expression}}}} follows the rules of Tornado templating language so no module is allowed to be imported. So for example you can't use now() as default value for a DateTime parameter. You need an if else block like this:
705
707
  <invalid_condition_with_now>
706
708
  AND timestamp BETWEEN {{DateTime(start_date, now() - interval 30 day)}} AND {{DateTime(end_date, now())}}
tinybird/tb/__cli__.py CHANGED
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
4
4
  __url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
5
5
  __author__ = 'Tinybird'
6
6
  __author_email__ = 'support@tinybird.co'
7
- __version__ = '0.0.1.dev35'
8
- __revision__ = '5046116'
7
+ __version__ = '0.0.1.dev36'
8
+ __revision__ = '5ad3ab4'
@@ -2,6 +2,7 @@ import asyncio
2
2
  import glob
3
3
  import json
4
4
  import logging
5
+ import os
5
6
  import threading
6
7
  import time
7
8
  from pathlib import Path
@@ -13,6 +14,7 @@ import requests
13
14
  from tinybird.client import TinyB
14
15
  from tinybird.tb.modules.cli import cli
15
16
  from tinybird.tb.modules.common import push_data
17
+ from tinybird.tb.modules.datafile.fixture import build_fixture_name, get_fixture_dir
16
18
  from tinybird.tb.modules.feedback_manager import FeedbackManager
17
19
  from tinybird.tb.modules.local_common import get_tinybird_local_client
18
20
  from tinybird.tb.modules.shell import Shell
@@ -20,7 +22,7 @@ from tinybird.tb.modules.watch import watch_project
20
22
 
21
23
 
22
24
  @cli.command()
23
- @click.option("--folder", type=str, default=".")
25
+ @click.option("--folder", type=str, default=os.getcwd())
24
26
  @click.option("--watch", is_flag=True, default=False, help="Watch for changes and rebuild automatically")
25
27
  def build(folder: str, watch: bool) -> None:
26
28
  """
@@ -30,11 +32,13 @@ def build(folder: str, watch: bool) -> None:
30
32
  tb_client = asyncio.run(get_tinybird_local_client(folder))
31
33
  click.echo(FeedbackManager.highlight(message="\n» Building project..."))
32
34
 
35
+ time_start = time.time()
36
+
33
37
  def process() -> None:
34
38
  build_project(folder, tb_client)
35
39
 
36
- time_start = time.time()
37
40
  process()
41
+
38
42
  time_end = time.time()
39
43
  elapsed_time = time_end - time_start
40
44
  click.echo(FeedbackManager.success(message=f"\n✓ Build completed in {elapsed_time:.1f}s"))
@@ -112,6 +116,20 @@ def build_project(folder: str, tb_client: TinyB) -> None:
112
116
  pipe_path = pipe_path.replace(f"{folder}/", "")
113
117
  click.echo(FeedbackManager.info(message=f"✓ {pipe_path} created"))
114
118
 
119
+ for filename in project_files:
120
+ if filename.endswith(".datasource"):
121
+ ds_path = Path(filename)
122
+ ds_name = ds_path.stem
123
+ name = build_fixture_name(filename, ds_name, ds_path.read_text())
124
+ fixture_folder = get_fixture_dir(folder)
125
+ fixture_path = fixture_folder / f"{name}.ndjson"
126
+
127
+ if not fixture_path.exists():
128
+ fixture_path = fixture_folder / f"{ds_name}.ndjson"
129
+
130
+ if fixture_path.exists():
131
+ append_fixture(tb_client, ds_name, str(fixture_path))
132
+
115
133
  elif build_result == "failed":
116
134
  click.echo(FeedbackManager.error(message="Build failed"))
117
135
  build_errors = result.get("errors")
@@ -121,24 +139,27 @@ def build_project(folder: str, tb_client: TinyB) -> None:
121
139
  click.echo(FeedbackManager.error(message=error_msg))
122
140
  else:
123
141
  click.echo(FeedbackManager.error(message=f"Unknown build result. Error: {result.get('error')}"))
142
+
124
143
  except Exception as e:
125
- click.echo(FeedbackManager.error_exception(error="Error building project: " + str(e)))
144
+ click.echo(FeedbackManager.error_exception(error="Error: " + str(e)))
126
145
  finally:
127
146
  for fd in fds:
128
147
  fd.close()
129
148
 
130
149
 
131
- async def append_fixture(
150
+ def append_fixture(
132
151
  tb_client: TinyB,
133
152
  datasource_name: str,
134
153
  url: str,
135
154
  ):
136
- await tb_client.datasource_truncate(datasource_name)
137
- await push_data(
138
- tb_client,
139
- datasource_name,
140
- url,
141
- mode="append",
142
- concurrency=1,
143
- silent=True,
155
+ asyncio.run(tb_client.datasource_truncate(datasource_name))
156
+ asyncio.run(
157
+ push_data(
158
+ tb_client,
159
+ datasource_name,
160
+ url,
161
+ mode="append",
162
+ concurrency=1,
163
+ silent=True,
164
+ )
144
165
  )
@@ -67,58 +67,13 @@ VERSION = f"{__cli__.__version__} (rev {__cli__.__revision__})"
67
67
  )
68
68
  @click.option("--token", help="Use auth token, defaults to TB_TOKEN envvar, then to the .tinyb file")
69
69
  @click.option("--host", help="Use custom host, defaults to TB_HOST envvar, then to https://api.tinybird.co")
70
- @click.option("--gcp-project-id", help="The Google Cloud project ID", hidden=True)
71
- @click.option(
72
- "--gcs-bucket", help="The Google Cloud Storage bucket to write temp files when using the connectors", hidden=True
73
- )
74
- @click.option(
75
- "--google-application-credentials",
76
- envvar="GOOGLE_APPLICATION_CREDENTIALS",
77
- help="Set GOOGLE_APPLICATION_CREDENTIALS",
78
- hidden=True,
79
- )
80
- @click.option("--sf-account", help="The Snowflake Account (e.g. your-domain.west-europe.azure)", hidden=True)
81
- @click.option("--sf-warehouse", help="The Snowflake warehouse name", hidden=True)
82
- @click.option("--sf-database", help="The Snowflake database name", hidden=True)
83
- @click.option("--sf-schema", help="The Snowflake schema name", hidden=True)
84
- @click.option("--sf-role", help="The Snowflake role name", hidden=True)
85
- @click.option("--sf-user", help="The Snowflake user name", hidden=True)
86
- @click.option("--sf-password", help="The Snowflake password", hidden=True)
87
- @click.option(
88
- "--sf-storage-integration",
89
- help="The Snowflake GCS storage integration name (leave empty to auto-generate one)",
90
- hidden=True,
91
- )
92
- @click.option("--sf-stage", help="The Snowflake GCS stage name (leave empty to auto-generate one)", hidden=True)
93
- @click.option(
94
- "--with-headers", help="Flag to enable connector to export with headers", is_flag=True, default=False, hidden=True
95
- )
96
70
  @click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens")
97
- @click.option("--prod/--local", is_flag=True, default=False, help="Run against production or local")
71
+ @click.option("--show-tokens", is_flag=True, default=False, help="Enable the output of tokens")
72
+ @click.option("--prod", is_flag=True, default=False, help="Run against production")
98
73
  @click.version_option(version=VERSION)
99
74
  @click.pass_context
100
75
  @coro
101
- async def cli(
102
- ctx: Context,
103
- debug: bool,
104
- token: str,
105
- host: str,
106
- gcp_project_id: str,
107
- gcs_bucket: str,
108
- google_application_credentials: str,
109
- sf_account: str,
110
- sf_warehouse: str,
111
- sf_database: str,
112
- sf_schema: str,
113
- sf_role: str,
114
- sf_user: str,
115
- sf_password: str,
116
- sf_storage_integration: str,
117
- sf_stage,
118
- with_headers: bool,
119
- show_tokens: bool,
120
- prod: bool,
121
- ) -> None:
76
+ async def cli(ctx: Context, debug: bool, token: str, host: str, show_tokens: bool, prod: bool) -> None:
122
77
  """
123
78
  Use `OBFUSCATE_REGEX_PATTERN` and `OBFUSCATE_PATTERN_SEPARATOR` environment variables to define a regex pattern and a separator (in case of a single string with multiple regex) to obfuscate secrets in the CLI output.
124
79
  """
@@ -166,51 +121,9 @@ async def cli(
166
121
 
167
122
  ctx.ensure_object(dict)["config"] = config
168
123
 
169
- if ctx.invoked_subcommand == "auth":
170
- return
171
-
172
- from tinybird.connectors import create_connector
173
-
174
- if gcp_project_id and gcs_bucket and google_application_credentials and not sf_account:
175
- bq_config = {
176
- "project_id": gcp_project_id,
177
- "bucket_name": gcs_bucket,
178
- "service_account": google_application_credentials,
179
- "with_headers": with_headers,
180
- }
181
- ctx.ensure_object(dict)["bigquery"] = create_connector("bigquery", bq_config)
182
- if (
183
- sf_account
184
- and sf_warehouse
185
- and sf_database
186
- and sf_schema
187
- and sf_role
188
- and sf_user
189
- and sf_password
190
- and gcs_bucket
191
- and google_application_credentials
192
- and gcp_project_id
193
- ):
194
- sf_config = {
195
- "account": sf_account,
196
- "warehouse": sf_warehouse,
197
- "database": sf_database,
198
- "schema": sf_schema,
199
- "role": sf_role,
200
- "user": sf_user,
201
- "password": sf_password,
202
- "storage_integration": sf_storage_integration,
203
- "stage": sf_stage,
204
- "bucket_name": gcs_bucket,
205
- "service_account": google_application_credentials,
206
- "project_id": gcp_project_id,
207
- "with_headers": with_headers,
208
- }
209
- ctx.ensure_object(dict)["snowflake"] = create_connector("snowflake", sf_config)
210
-
211
124
  logging.debug("debug enabled")
212
125
 
213
- skip_client = ctx.invoked_subcommand in ["login", "workspace", "local", "build"]
126
+ skip_client = ctx.invoked_subcommand in ["auth", "login", "workspace", "local", "build"]
214
127
  client = await create_ctx_client(config, prod, skip_client)
215
128
 
216
129
  if client:
@@ -487,7 +400,7 @@ async def sql(
487
400
 
488
401
  @cli.command(hidden=True)
489
402
  @click.argument("prompt")
490
- @click.option("--folder", default=".", help="The folder to use for the project")
403
+ @click.option("--folder", default=os.getcwd(), help="The folder to use for the project")
491
404
  @coro
492
405
  async def ask(prompt: str, folder: str) -> None:
493
406
  """Ask things about your data project."""
@@ -529,8 +442,8 @@ async def ask(prompt: str, folder: str) -> None:
529
442
  )
530
443
 
531
444
  client = config.get_client()
532
- llm = LLM(user_token=user_token, client=client)
533
- click.echo(await llm.ask(system_prompt=ask_prompt(resources_xml), prompt=prompt))
445
+ llm = LLM(user_token=user_token, host=client.host)
446
+ click.echo(llm.ask(system_prompt=ask_prompt(resources_xml), prompt=prompt))
534
447
  except Exception as e:
535
448
  raise CLIException(FeedbackManager.error_exception(error=e))
536
449
 
@@ -103,13 +103,13 @@ async def create(
103
103
  datasource_files = [f for f in os.listdir(Path(folder) / "datasources") if f.endswith(".datasource")]
104
104
  for datasource_file in datasource_files:
105
105
  datasource_path = Path(folder) / "datasources" / datasource_file
106
- llm = LLM(user_token=user_token, client=tb_client)
106
+ llm = LLM(user_token=user_token, host=tb_client.host)
107
107
  datasource_name = datasource_path.stem
108
108
  datasource_content = datasource_path.read_text()
109
109
  has_json_path = "`json:" in datasource_content
110
110
  if has_json_path:
111
111
  prompt = f"<datasource_schema>{datasource_content}</datasource_schema>\n<user_input>{prompt}</user_input>"
112
- response = await llm.ask(system_prompt=mock_prompt(rows), prompt=prompt)
112
+ response = llm.ask(system_prompt=mock_prompt(rows), prompt=prompt)
113
113
  sql = extract_xml(response, "sql")
114
114
  sql = sql.split("FORMAT")[0]
115
115
  result = await local_client.query(f"{sql} FORMAT JSON")
@@ -205,8 +205,8 @@ TYPE ENDPOINT
205
205
  ]
206
206
  ]
207
207
  )
208
- llm = LLM(user_token=user_token, client=tb_client)
209
- result = await llm.ask(system_prompt=create_prompt(resources_xml), prompt=prompt)
208
+ llm = LLM(user_token=user_token, host=tb_client.host)
209
+ result = llm.ask(system_prompt=create_prompt(resources_xml), prompt=prompt)
210
210
  result = extract_xml(result, "response")
211
211
  resources = parse_xml(result, "resource")
212
212
  datasources = []
@@ -44,7 +44,7 @@ from tinybird.tb.modules.datafile.exceptions import AlreadyExistsException, Incl
44
44
  from tinybird.tb.modules.datafile.parse_datasource import parse_datasource
45
45
  from tinybird.tb.modules.datafile.parse_pipe import parse_pipe
46
46
  from tinybird.tb.modules.feedback_manager import FeedbackManager
47
- from tinybird.tb.modules.local_common import get_client_config_for_build
47
+ from tinybird.tb.modules.local_common import get_tinybird_local_config
48
48
 
49
49
 
50
50
  async def folder_build(
@@ -58,7 +58,7 @@ async def folder_build(
58
58
  local_ws: Optional[Dict[str, Any]] = None,
59
59
  watch: bool = False,
60
60
  ):
61
- config = await get_client_config_for_build(folder)
61
+ config = await get_tinybird_local_config(folder)
62
62
  build = True
63
63
  dry_run = False
64
64
  force = True
@@ -1,19 +1,16 @@
1
- from copy import deepcopy
2
- from typing import Optional
3
-
4
- from tinybird.client import TinyB
1
+ import requests
5
2
 
6
3
 
7
4
  class LLM:
8
5
  def __init__(
9
6
  self,
7
+ host: str,
10
8
  user_token: str,
11
- client: TinyB,
12
9
  ):
13
- self.user_client = deepcopy(client)
14
- self.user_client.token = user_token
10
+ self.host = host
11
+ self.user_token = user_token
15
12
 
16
- async def ask(self, system_prompt: str, prompt: Optional[str] = None) -> str:
13
+ def ask(self, system_prompt: str, prompt: str) -> str:
17
14
  """
18
15
  Calls the model with the given prompt and returns the response.
19
16
 
@@ -25,14 +22,11 @@ class LLM:
25
22
  str: The response from the language model.
26
23
  """
27
24
 
28
- data = {"system": system_prompt}
29
-
30
- if prompt:
31
- data["prompt"] = prompt
25
+ data = {"system": system_prompt, "prompt": prompt}
32
26
 
33
- response = await self.user_client._req(
34
- "/v0/llm",
35
- method="POST",
27
+ response = requests.post(
28
+ f"{self.host}/v0/llm",
29
+ headers={"Authorization": f"Bearer {self.user_token}"},
36
30
  data=data,
37
31
  )
38
- return response.get("result", "")
32
+ return response.json().get("result", "")
@@ -22,3 +22,90 @@ def parse_xml(text: str, tag: str) -> List[str]:
22
22
  Parses the text for the specified XML tag and returns a list of the contents of each tag.
23
23
  """
24
24
  return re.findall(f"<{tag}.*?>(.*?)</{tag}>", text, re.DOTALL)
25
+
26
+
27
+ def generate(llm_call, task: str, context: str = "") -> tuple[str, str]:
28
+ """Generate and improve a solution based on feedback."""
29
+ task = f"<task>\n{task}\n</task>"
30
+ full_prompt = (
31
+ f"{generator_prompt}\n<context>\n{context}\n</context>\n{task}" if context else f"{generator_prompt}\n{task}"
32
+ )
33
+ response = llm_call(full_prompt)
34
+ thoughts = extract_xml(response, "thoughts")
35
+ result = extract_xml(response, "response")
36
+
37
+ return thoughts, result
38
+
39
+
40
+ def evaluate(llm_call, content: str, task: str) -> tuple[str, str]:
41
+ """Evaluate if a solution meets requirements."""
42
+ full_prompt = f"{evaluator_prompt}\n<original_task>\n{task}\n</original_task>\n<content_to_evaluate>\n{content}\n</content_to_evaluate>"
43
+ response = llm_call(full_prompt)
44
+ evaluation = extract_xml(response, "evaluation")
45
+ feedback = extract_xml(response, "feedback")
46
+
47
+ return evaluation, feedback
48
+
49
+
50
+ def loop(llm_call, task: str) -> str:
51
+ """Keep generating and evaluating until requirements are met."""
52
+ memory = []
53
+ chain_of_thought = []
54
+
55
+ thoughts, result = generate(llm_call, task)
56
+ memory.append(result)
57
+ chain_of_thought.append({"thoughts": thoughts, "result": result})
58
+
59
+ attempts = 0
60
+ while True:
61
+ if attempts > 5:
62
+ raise Exception("Failed to generate a valid solution")
63
+
64
+ evaluation, feedback = evaluate(llm_call, result, task)
65
+ if evaluation == "PASS":
66
+ return result
67
+
68
+ context = "\n".join(
69
+ [
70
+ "Previous attempts:",
71
+ *[f"- {m}" for m in memory],
72
+ f"\nFeedback: {feedback}",
73
+ ]
74
+ )
75
+
76
+ thoughts, result = generate(llm_call, task, context)
77
+ memory.append(result)
78
+ chain_of_thought.append({"thoughts": thoughts, "result": result})
79
+
80
+ attempts += 1
81
+
82
+
83
+ evaluator_prompt = """
84
+ Evaluate this following code implementation for code correctness taking into account the user prompt and the instructions provided.
85
+
86
+ You should be evaluating only and not attemping to solve the task.
87
+ Only output "PASS" if all criteria are met and the code won't fail at runtime.
88
+ Output your evaluation concisely in the following format:
89
+
90
+ <evaluation>PASS or FAIL</evaluation>
91
+ <feedback>
92
+ [What is wrong with the code and how to fix it]
93
+ </feedback>
94
+ """
95
+
96
+ generator_prompt = """
97
+ Your goal is to complete the task based on <task> tag. If there are feedback
98
+ from your previous generations, you should reflect on them to improve your solution
99
+
100
+ Output your answer concisely in the following format:
101
+
102
+ <thoughts>
103
+ [Your understanding of the task and feedback and how you plan to improve]
104
+ </thoughts>
105
+
106
+ <response>
107
+ [Your code implementation here]
108
+ </response>
109
+
110
+ The code implementation should not be wrapped in any markdown format.
111
+ """
@@ -17,11 +17,11 @@ TB_LOCAL_HOST = f"http://localhost:{TB_LOCAL_PORT}"
17
17
 
18
18
  async def get_tinybird_local_client(path: Optional[str] = None) -> TinyB:
19
19
  """Get a Tinybird client connected to the local environment."""
20
- config = await get_client_config_for_build(path)
20
+ config = await get_tinybird_local_config(path)
21
21
  return config.get_client(host=TB_LOCAL_HOST)
22
22
 
23
23
 
24
- async def get_client_config_for_build(path: Optional[str] = None) -> CLIConfig:
24
+ async def get_tinybird_local_config(path: Optional[str] = None) -> CLIConfig:
25
25
  """Craft a client config with a workspace name based on the path of the project files
26
26
 
27
27
  It uses the tokens from tinybird local
@@ -24,7 +24,7 @@ from tinybird.tb.modules.local_common import get_tinybird_local_client
24
24
  default="Use the datasource schema to generate sample data",
25
25
  help="Extra context to use for data generation",
26
26
  )
27
- @click.option("--folder", type=str, default=".", help="Folder where datafiles will be placed")
27
+ @click.option("--folder", type=str, default=os.getcwd(), help="Folder where datafiles will be placed")
28
28
  @coro
29
29
  async def mock(datasource: str, rows: int, prompt: str, folder: str) -> None:
30
30
  """Load sample data into a Data Source.
@@ -67,11 +67,10 @@ async def mock(datasource: str, rows: int, prompt: str, folder: str) -> None:
67
67
  except Exception:
68
68
  click.echo(FeedbackManager.error(message="This action requires authentication. Run 'tb login' first."))
69
69
  return
70
- user_client.token = user_token
71
- llm = LLM(user_token=user_token, client=user_client)
70
+ llm = LLM(user_token=user_token, host=user_client.host)
72
71
  tb_client = await get_tinybird_local_client(os.path.abspath(folder))
73
72
  prompt = f"<datasource_schema>{datasource_content}</datasource_schema>\n<user_input>{prompt}</user_input>"
74
- response = await llm.ask(system_prompt=mock_prompt(rows), prompt=prompt)
73
+ response = llm.ask(system_prompt=mock_prompt(rows), prompt=prompt)
75
74
  sql = extract_xml(response, "sql")
76
75
  if os.environ.get("TB_DEBUG", "") != "":
77
76
  logging.debug(sql)
@@ -111,9 +111,9 @@ async def test_create(name_or_filename: str, prompt: str, folder: str) -> None:
111
111
  user_token = config.get_user_token()
112
112
  if not user_token:
113
113
  raise CLIException(FeedbackManager.error(message="No user token found"))
114
- llm = LLM(user_token=user_token, client=config.get_client())
114
+ llm = LLM(user_token=user_token, host=config.get_client().host)
115
115
 
116
- response_llm = await llm.ask(system_prompt=system_prompt, prompt=prompt)
116
+ response_llm = llm.ask(system_prompt=system_prompt, prompt=prompt)
117
117
  response_xml = extract_xml(response_llm, "response")
118
118
  tests_content = parse_xml(response_xml, "test")
119
119
 
@@ -65,13 +65,13 @@ async def update(
65
65
  datasource_files = [f for f in os.listdir(Path(folder) / "datasources") if f.endswith(".datasource")]
66
66
  for datasource_file in datasource_files:
67
67
  datasource_path = Path(folder) / "datasources" / datasource_file
68
- llm = LLM(user_token=user_token, client=tb_client)
68
+ llm = LLM(user_token=user_token, host=tb_client.host)
69
69
  datasource_name = datasource_path.stem
70
70
  datasource_content = datasource_path.read_text()
71
71
  has_json_path = "`json:" in datasource_content
72
72
  if has_json_path:
73
73
  prompt = f"<datasource_schema>{datasource_content}</datasource_schema>\n<user_input>{prompt}</user_input>"
74
- response = await llm.ask(system_prompt=mock_prompt(rows=20), prompt=prompt)
74
+ response = llm.ask(system_prompt=mock_prompt(rows=20), prompt=prompt)
75
75
  sql = extract_xml(response, "sql")
76
76
  sql = sql.split("FORMAT")[0]
77
77
  result = await local_client.query(f"{sql} FORMAT JSON")
@@ -116,8 +116,8 @@ async def update_resources(
116
116
  ]
117
117
  ]
118
118
  )
119
- llm = LLM(user_token=user_token, client=tb_client)
120
- result = await llm.ask(system_prompt=update_prompt(resources_xml), prompt=prompt)
119
+ llm = LLM(user_token=user_token, host=tb_client.host)
120
+ result = llm.ask(system_prompt=update_prompt(resources_xml), prompt=prompt)
121
121
  result = extract_xml(result, "response")
122
122
  resources = parse_xml(result, "resource")
123
123
  datasources = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinybird
3
- Version: 0.0.1.dev35
3
+ Version: 0.0.1.dev36
4
4
  Summary: Tinybird Command Line Tool
5
5
  Home-page: https://www.tinybird.co/docs/cli/introduction.html
6
6
  Author: Tinybird
@@ -6,7 +6,7 @@ tinybird/context.py,sha256=A3GBApac9xO6hrAMJ1s9dMrI_ou9aKF84CdEjtPddMk,1417
6
6
  tinybird/datatypes.py,sha256=XNypumfqNjsvLJ5iNXnbVHRvAJe0aQwI3lS6Cxox-e0,10979
7
7
  tinybird/feedback_manager.py,sha256=ON5Zu-G3-QDVfH2i_P-V4EtyhlNtAzyp1YDZsnce0_U,67826
8
8
  tinybird/git_settings.py,sha256=Sw_8rGmribEFJ4Z_6idrVytxpFYk7ez8ei0qHULzs3E,3934
9
- tinybird/prompts.py,sha256=A7RdXLc0jbn33RlaMVcp8l-jAccg4QxpBgepfyhktlA,24347
9
+ tinybird/prompts.py,sha256=bsJoaZwMz_Bp1d_PKG4IcwmC9Ym6ybomOxhJEREnGFg,24447
10
10
  tinybird/sql.py,sha256=eulpRe05ZFrKFrxYawgxDxxrktFE8uL6hSL1gHIWKyg,46166
11
11
  tinybird/sql_template.py,sha256=GmMLAI10MTqjQo9qztuQHLRWs67teozsWDxUBdvkAn4,93668
12
12
  tinybird/sql_template_fmt.py,sha256=1z-PuqSZXtzso8Z_mPqUc-NxIxUrNUcVIPezNieZk-M,10196
@@ -15,16 +15,16 @@ tinybird/syncasync.py,sha256=IPnOx6lMbf9SNddN1eBtssg8vCLHMt76SuZ6YNYm-Yk,27761
15
15
  tinybird/tornado_template.py,sha256=oflXyoL2LSCegvl6bAzqw2JIqRaN5WPjhYYDtQcfuOE,41869
16
16
  tinybird/ch_utils/constants.py,sha256=aYvg2C_WxYWsnqPdZB1ZFoIr8ZY-XjUXYyHKE9Ansj0,3890
17
17
  tinybird/ch_utils/engine.py,sha256=OXkBhlzGjZotjD0vaT-rFIbSGV4tpiHxE8qO_ip0SyQ,40454
18
- tinybird/tb/__cli__.py,sha256=SARg8d4VPUneNfQ1Vb_nmb5NwGlbDpdJmlcUcx4ndLo,251
18
+ tinybird/tb/__cli__.py,sha256=QN6VNkkasc3obkNsTbIuaRrlLedAlQzKqfqLF83fnhY,251
19
19
  tinybird/tb/cli.py,sha256=VKHKQ2mmkTgbu5sKa60Xz08QbD8kCtBhYjLLiXNOcWI,925
20
20
  tinybird/tb/modules/auth.py,sha256=EzRWFmwRkXNhUmRaruEVFLdkbUg8xMSix0cAWl5D4Jg,9029
21
- tinybird/tb/modules/build.py,sha256=tJpgjCJhq_wsSQTcMHbNSNgF2ELSs6zqtfSn8Bfl7pw,5305
21
+ tinybird/tb/modules/build.py,sha256=02dqajEybhFP3LdnaDOi-WaRf6mrJ1Gxs4y5nZfbNcs,6097
22
22
  tinybird/tb/modules/build_client.py,sha256=uAfFoHae0rUwAmiWt843YkA5iUa0PcUTn-LqGyAlmtM,7379
23
23
  tinybird/tb/modules/cicd.py,sha256=SjCyvvy0WUnsjFs2biwwXvcf0Ddpmghhd8-SnMyfsRM,5355
24
- tinybird/tb/modules/cli.py,sha256=g7-BlVGTBFxOPJpDz0cLs6AyfQPM1p4xEuIUgNFDsgk,22159
24
+ tinybird/tb/modules/cli.py,sha256=SOyNAyebxBLEHg_3VXrbNYeWXwfxG3VoAVAWOlWnAbo,19160
25
25
  tinybird/tb/modules/common.py,sha256=e4U7AT0dUBG6O-7Iq2CVN1UHPd6-ZCFucyW0L5gBi4g,70592
26
26
  tinybird/tb/modules/config.py,sha256=mie3oMVTf5YOUFEiLs88P16U4LkJafJjSpjwyAkFHog,10979
27
- tinybird/tb/modules/create.py,sha256=HclKekBKTaobVQeYq9ooSmuBwlrebi-YsFOFJJMGTZs,10860
27
+ tinybird/tb/modules/create.py,sha256=x-lXLlr9d0kvkdqHbioA0m-hgutRXWeJS_pjJjoqrFM,10854
28
28
  tinybird/tb/modules/datasource.py,sha256=-VG2qKlu0fmkhsIB5bPiTp3XuktB_r-ZkIoohEBEXtI,13713
29
29
  tinybird/tb/modules/deployment.py,sha256=xy89tZAXHMrg78yh-4TZWxnAeQJe8SbC-1xXg96lyc8,9704
30
30
  tinybird/tb/modules/endpoint.py,sha256=iYSWzi3_VJzHcq1_j_Hv4cfG1GFKXKxqEY4jLjKhxag,6488
@@ -32,25 +32,25 @@ tinybird/tb/modules/exceptions.py,sha256=4A2sSjCEqKUMqpP3WI00zouCWW4uLaghXXLZBSw
32
32
  tinybird/tb/modules/feedback_manager.py,sha256=e8tqehRR0Buhs8O0n8N2Sg2vnnBVb1NLtnZqkPrYD_A,68379
33
33
  tinybird/tb/modules/fmt.py,sha256=poh6_cwVGSf-sBu6LKWuO2TANL_J8Sgm25sPpwxa3Aw,3558
34
34
  tinybird/tb/modules/job.py,sha256=956Pj8BEEsiD2GZsV9RKKVM3I_CveOLgS82lykO5ukk,2963
35
- tinybird/tb/modules/llm.py,sha256=mguBJaTJ74a5mQXcBQwbCjKugfvcFm_Wzg2e_hSkooQ,953
36
- tinybird/tb/modules/llm_utils.py,sha256=hIfBU7vMUHUt25pljim3WdZdJTNr9hDo3mHezqI5B7w,766
35
+ tinybird/tb/modules/llm.py,sha256=AC0VSphTOM2t-v1_3NLvNN_FIbgMo4dTyMqIv5nniPo,835
36
+ tinybird/tb/modules/llm_utils.py,sha256=ZijatIp7XzzWI1qp4DHyj1GgBIZdntBUF0YFZndhJW8,3558
37
37
  tinybird/tb/modules/local.py,sha256=x4xuCGVkoa8KLYGZEJnFUP8HUkKX05Frp_djRVjVjTs,5669
38
- tinybird/tb/modules/local_common.py,sha256=iQJHZs5D_luLrbyZOMjqi3Cj65YavDDKYPZDSE8E9lo,2519
38
+ tinybird/tb/modules/local_common.py,sha256=8UXRJzujHb6bAro7xZpmftzLD4v2XAOCn9Z5hKAcRZ4,2515
39
39
  tinybird/tb/modules/login.py,sha256=0cS-f3MsQFHc6xjw8FRWJm4EJBH9C7Ri68EcO_tiwes,6508
40
- tinybird/tb/modules/mock.py,sha256=YUmqkhfOy8Mmu1zsb3fCford5Tix289R7UrlylRvN04,3733
40
+ tinybird/tb/modules/mock.py,sha256=TdqAQwF73b95_EVBFVHH0gOghtm3fuMsMCsddCEsZAY,3699
41
41
  tinybird/tb/modules/pipe.py,sha256=7NPrtvF76PKvrL9GZyco9xgWbvfesV31vssuAlTbXgM,17858
42
42
  tinybird/tb/modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
43
43
  tinybird/tb/modules/shell.py,sha256=dcc0ziFlJ-WSMAq6oH_UF0y3omXTdoJfF_Vi4U8FEmk,13362
44
44
  tinybird/tb/modules/table.py,sha256=4XrtjM-N0zfNtxVkbvLDQQazno1EPXnxTyo7llivfXk,11035
45
45
  tinybird/tb/modules/tag.py,sha256=anPmMUBc-TbFovlpFi8GPkKA18y7Y0GczMsMms5TZsU,3502
46
46
  tinybird/tb/modules/telemetry.py,sha256=iEGnMuCuNhvF6ln__j6X9MSTwL_0Hm-GgFHHHvhfknk,10466
47
- tinybird/tb/modules/test.py,sha256=q-nO-s9cA7SpFSg0uTvfwtp8V69CjxKuK9iQ1alIPEU,11618
47
+ tinybird/tb/modules/test.py,sha256=vPyAOfiUUawbBu3CjEXEziGD9A6-GzFdJ7G2WohopTc,11615
48
48
  tinybird/tb/modules/token.py,sha256=AePr-QMv_vtWwZDWQ92Zp0kPrCjze61i4npiPhoLMZg,12717
49
- tinybird/tb/modules/update.py,sha256=wXzLhBzKD1kWEN1HejOVkKpFQqomZGfP1AiCvE-K04A,6827
49
+ tinybird/tb/modules/update.py,sha256=RCOGhxJPhlwCzRzPPYFfbvpJeDKu3yEISWUJinr953M,6821
50
50
  tinybird/tb/modules/watch.py,sha256=Wr_JkoxO0FKY8DXkbGxkq0wagdk2gUtIUcRZTOv9Et8,6293
51
51
  tinybird/tb/modules/workspace.py,sha256=M0RtXCaw7RdZ3c_fqtmjbVb7HqlV742Drn4OiyZlp3M,6345
52
52
  tinybird/tb/modules/workspace_members.py,sha256=Ai6iCOzXX1zQ8q9iXIFSFHsBJlT-8Q28DaG5Ie-UweY,8726
53
- tinybird/tb/modules/datafile/build.py,sha256=HmRWxAjRrpgnlqpNeLaZSlsY1AZ_sAGYa0mNmfe9X9g,57581
53
+ tinybird/tb/modules/datafile/build.py,sha256=pwgsIuvHwb2cdsl3IWOAPyj6S9vB3jn_BXGRcKT7I2Y,57577
54
54
  tinybird/tb/modules/datafile/build_common.py,sha256=IXl-Z51zUi1dypV7meNenX0iu2UmowNeqgG6WHyMHlk,4562
55
55
  tinybird/tb/modules/datafile/build_datasource.py,sha256=4aP8_DYCRGghXntZSeWDNJxjps1QRVa7WHoYCzQwQts,17355
56
56
  tinybird/tb/modules/datafile/build_pipe.py,sha256=Jgv3YKIvMfjPiSIdw1k2mpaoDdAWMiMRaSHwRgyI97E,28258
@@ -73,8 +73,8 @@ tinybird/tb_cli_modules/config.py,sha256=6u6B5QCdiQLbJkCkwtnKGs9H3nP-KXXhC75mF7B
73
73
  tinybird/tb_cli_modules/exceptions.py,sha256=pmucP4kTF4irIt7dXiG-FcnI-o3mvDusPmch1L8RCWk,3367
74
74
  tinybird/tb_cli_modules/regions.py,sha256=QjsL5H6Kg-qr0aYVLrvb1STeJ5Sx_sjvbOYO0LrEGMk,166
75
75
  tinybird/tb_cli_modules/telemetry.py,sha256=iEGnMuCuNhvF6ln__j6X9MSTwL_0Hm-GgFHHHvhfknk,10466
76
- tinybird-0.0.1.dev35.dist-info/METADATA,sha256=GOshgB7vaTtqHYSkYCbffl0E2PWu9Gg0HkbK_LjIJqg,2482
77
- tinybird-0.0.1.dev35.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
78
- tinybird-0.0.1.dev35.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
79
- tinybird-0.0.1.dev35.dist-info/top_level.txt,sha256=pgw6AzERHBcW3YTi2PW4arjxLkulk2msOz_SomfOEuc,45
80
- tinybird-0.0.1.dev35.dist-info/RECORD,,
76
+ tinybird-0.0.1.dev36.dist-info/METADATA,sha256=rPYWLp2_2IWLJYIDOYfxJZoIQFY_9L82n9QkcXASV0k,2482
77
+ tinybird-0.0.1.dev36.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
78
+ tinybird-0.0.1.dev36.dist-info/entry_points.txt,sha256=LwdHU6TfKx4Qs7BqqtaczEZbImgU7Abe9Lp920zb_fo,43
79
+ tinybird-0.0.1.dev36.dist-info/top_level.txt,sha256=pgw6AzERHBcW3YTi2PW4arjxLkulk2msOz_SomfOEuc,45
80
+ tinybird-0.0.1.dev36.dist-info/RECORD,,