tinybird 0.0.1.dev252__tar.gz → 0.0.1.dev254__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tinybird might be problematic. Click here for more details.
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/PKG-INFO +1 -1
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/__cli__.py +2 -2
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/agent.py +66 -34
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/prompts.py +237 -0
- tinybird-0.0.1.dev254/tinybird/tb/modules/agent/tools/analyze.py +79 -0
- tinybird-0.0.1.dev254/tinybird/tb/modules/agent/tools/append.py +87 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/deploy_check.py +16 -1
- tinybird-0.0.1.dev254/tinybird/tb/modules/agent/tools/execute_query.py +61 -0
- tinybird-0.0.1.dev254/tinybird/tb/modules/agent/tools/request_endpoint.py +65 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/utils.py +4 -2
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/cli.py +8 -2
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/PKG-INFO +1 -1
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/SOURCES.txt +3 -1
- tinybird-0.0.1.dev252/tinybird/tb/modules/agent/tools/append.py +0 -47
- tinybird-0.0.1.dev252/tinybird/tb/modules/agent/tools/read_fixture_data.py +0 -36
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/setup.cfg +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/__cli__.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/check_pypi.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/client.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/config.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/connectors.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/context.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datafile/common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/datatypes.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/git_settings.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/prompts.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/sql.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/sql_template.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/sql_toolset.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/syncasync.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/cli.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/client.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/config.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/__init__.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/animations.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/banner.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/memory.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/models.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/build.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/create_datafile.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/explore.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/mock.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/plan.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/preview_datafile.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/build.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/config.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/create.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/deployment_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/dev_server.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/info.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/job.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/local.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/login.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/mock.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/mock_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/open.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/project.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/shell.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/table.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/test.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/token.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tornado_template.py +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -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.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '0.0.1.dev254'
|
|
8
|
+
__revision__ = '269e345'
|
|
@@ -30,22 +30,24 @@ from tinybird.tb.modules.agent.memory import clear_history
|
|
|
30
30
|
from tinybird.tb.modules.agent.models import create_model, model_costs
|
|
31
31
|
from tinybird.tb.modules.agent.prompts import (
|
|
32
32
|
datafile_instructions,
|
|
33
|
+
endpoint_optimization_instructions,
|
|
33
34
|
plan_instructions,
|
|
34
35
|
resources_prompt,
|
|
35
36
|
sql_instructions,
|
|
36
37
|
)
|
|
37
|
-
from tinybird.tb.modules.agent.tools.
|
|
38
|
+
from tinybird.tb.modules.agent.tools.analyze import analyze_file, analyze_url
|
|
39
|
+
from tinybird.tb.modules.agent.tools.append import append_file, append_url
|
|
38
40
|
from tinybird.tb.modules.agent.tools.build import build
|
|
39
41
|
from tinybird.tb.modules.agent.tools.create_datafile import create_datafile
|
|
40
42
|
from tinybird.tb.modules.agent.tools.deploy import deploy
|
|
41
43
|
from tinybird.tb.modules.agent.tools.deploy_check import deploy_check
|
|
42
|
-
from tinybird.tb.modules.agent.tools.
|
|
44
|
+
from tinybird.tb.modules.agent.tools.execute_query import execute_query
|
|
43
45
|
from tinybird.tb.modules.agent.tools.get_endpoint_stats import get_endpoint_stats
|
|
44
46
|
from tinybird.tb.modules.agent.tools.get_openapi_definition import get_openapi_definition
|
|
45
47
|
from tinybird.tb.modules.agent.tools.mock import mock
|
|
46
48
|
from tinybird.tb.modules.agent.tools.plan import plan
|
|
47
49
|
from tinybird.tb.modules.agent.tools.preview_datafile import preview_datafile
|
|
48
|
-
from tinybird.tb.modules.agent.tools.
|
|
50
|
+
from tinybird.tb.modules.agent.tools.request_endpoint import request_endpoint
|
|
49
51
|
from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_input
|
|
50
52
|
from tinybird.tb.modules.build_common import process as build_process
|
|
51
53
|
from tinybird.tb.modules.common import _analyze, _get_tb_client
|
|
@@ -104,18 +106,21 @@ IMPORTANT: DO NOT ADD ANY COMMENTS unless asked by the user.
|
|
|
104
106
|
|
|
105
107
|
# Tools
|
|
106
108
|
You have access to the following tools:
|
|
107
|
-
1. `
|
|
108
|
-
2. `
|
|
109
|
-
3. `
|
|
110
|
-
4. `
|
|
111
|
-
5. `
|
|
112
|
-
6. `
|
|
113
|
-
7. `
|
|
114
|
-
8. `
|
|
115
|
-
9. `
|
|
116
|
-
|
|
109
|
+
1. `preview_datafile` - Preview the content of a datafile (datasource, endpoint, materialized, sink, copy, connection).
|
|
110
|
+
2. `create_datafile` - Create a file in the project folder. Confirmation will be asked by the tool before creating the file.
|
|
111
|
+
3. `plan` - Plan the creation or update of resources.
|
|
112
|
+
4. `build` - Build the project.
|
|
113
|
+
5. `deploy` - Deploy the project to Tinybird Cloud.
|
|
114
|
+
6. `deploy_check` - Check if the project can be deployed to Tinybird Cloud before deploying it.
|
|
115
|
+
7. `mock` - Create mock data for a landing datasource.
|
|
116
|
+
8. `analyze_file` - Analyze the content of a fixture file present in the project folder.
|
|
117
|
+
9. `analyze_url` - Analyze the content of an external url.
|
|
118
|
+
9. `append_file` - Append a file present in the project to a datasource.
|
|
119
|
+
10. `append_url` - Append an external url to a datasource.
|
|
117
120
|
11. `get_endpoint_stats` - Get metrics of the requests to an endpoint.
|
|
118
121
|
12. `get_openapi_definition` - Get the OpenAPI definition for all endpoints that are built/deployed to Tinybird Cloud or Local.
|
|
122
|
+
13. `execute_query` - Execute a query against Tinybird Cloud or Local.
|
|
123
|
+
13. `request_endpoint` - Request an endpoint against Tinybird Cloud or Local.
|
|
119
124
|
|
|
120
125
|
# When creating or updating datafiles:
|
|
121
126
|
1. Use `plan` tool to plan the creation or update of resources.
|
|
@@ -131,23 +136,20 @@ You have access to the following tools:
|
|
|
131
136
|
- If the user does not specify anything about the desired schema, create a schema like this:
|
|
132
137
|
SCHEMA >
|
|
133
138
|
`data` String `json:$`
|
|
139
|
+
|
|
134
140
|
- Use always json paths with .ndjson files.
|
|
135
141
|
|
|
136
142
|
# When user wants to optimize an endpoint:
|
|
137
|
-
|
|
138
|
-
Avoid when possible to not update the landing datasource.
|
|
139
|
-
Check endpoint stats to analyze how the endpoint is performing. Use `get_endpoint_stats` tool to get the stats.
|
|
140
|
-
When your data is in Tinybird, you can create intermediate data sources to preprocess data and make the endpoints faster. This can be done by using materialized views or copy pipes.
|
|
141
|
-
- Copy pipes capture the result of a pipe at a specific point in time and write it to a target data source. They can run on a schedule or run on demand, making them ideal for event-sourced snapshots, data experimentation, and deduplication with snapshots.
|
|
142
|
-
- Materialized views continuously re-evaluate a query as new events are inserted, maintaining an always up-to-date derived dataset. Unlike copy pipes which create point-in-time snapshots, materialized views provide real-time transformations of your data.
|
|
143
|
-
Each approach has its own strengths and use cases:
|
|
144
|
-
- Use copy pipes when you need scheduled or on-demand snapshots of your data.
|
|
145
|
-
- Use materialized views when you need continuous, real-time transformations.
|
|
146
|
-
Finally, update the existing endpoint itself, do not add a new one.
|
|
143
|
+
{endpoint_optimization_instructions}
|
|
147
144
|
|
|
148
145
|
IMPORTANT: If the user cancels some of the steps or there is an error in file creation, DO NOT continue with the plan. Stop the process and wait for the user before using any other tool.
|
|
149
146
|
IMPORTANT: Every time you finish a plan and start a new resource creation or update process, create a new plan before starting with the changes.
|
|
150
147
|
|
|
148
|
+
# Using deployment tools:
|
|
149
|
+
- Use `deploy_check` tool to check if the project can be deployed to Tinybird Cloud before deploying it.
|
|
150
|
+
- Use `deploy` tool to deploy the project to Tinybird Cloud.
|
|
151
|
+
- Only use deployment tools if user explicitly asks for it.
|
|
152
|
+
|
|
151
153
|
# When planning the creation or update of resources:
|
|
152
154
|
{plan_instructions}
|
|
153
155
|
{datafile_instructions}
|
|
@@ -184,7 +186,6 @@ GCS: {gcs_connection_example}
|
|
|
184
186
|
Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
185
187
|
""",
|
|
186
188
|
tools=[
|
|
187
|
-
Tool(explore_data, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
188
189
|
Tool(preview_datafile, docstring_format="google", require_parameter_descriptions=True, takes_ctx=False),
|
|
189
190
|
Tool(create_datafile, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
190
191
|
Tool(plan, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
@@ -192,8 +193,10 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
|
192
193
|
Tool(deploy, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
193
194
|
Tool(deploy_check, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
194
195
|
Tool(mock, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
195
|
-
Tool(
|
|
196
|
-
Tool(
|
|
196
|
+
Tool(analyze_file, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
197
|
+
Tool(analyze_url, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
198
|
+
Tool(append_file, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
199
|
+
Tool(append_url, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
197
200
|
Tool(
|
|
198
201
|
get_endpoint_stats, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True
|
|
199
202
|
),
|
|
@@ -203,6 +206,8 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
|
203
206
|
require_parameter_descriptions=True,
|
|
204
207
|
takes_ctx=True,
|
|
205
208
|
),
|
|
209
|
+
Tool(execute_query, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
210
|
+
Tool(request_endpoint, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
206
211
|
],
|
|
207
212
|
)
|
|
208
213
|
|
|
@@ -230,6 +235,8 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
|
230
235
|
analyze_fixture=partial(analyze_fixture, config=config),
|
|
231
236
|
execute_cloud_query=partial(execute_cloud_query, config=config),
|
|
232
237
|
execute_local_query=partial(execute_local_query, config=config),
|
|
238
|
+
request_endpoint_cloud=partial(request_endpoint_cloud, config=config),
|
|
239
|
+
request_endpoint_local=partial(request_endpoint_local, config=config),
|
|
233
240
|
get_project_files=project.get_project_files,
|
|
234
241
|
folder=folder,
|
|
235
242
|
thinking_animation=thinking_animation,
|
|
@@ -263,12 +270,14 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
|
263
270
|
click.echo("\n")
|
|
264
271
|
|
|
265
272
|
|
|
266
|
-
def run_agent(
|
|
273
|
+
def run_agent(
|
|
274
|
+
config: dict[str, Any], project: Project, dangerously_skip_permissions: bool, prompt: Optional[str] = None
|
|
275
|
+
):
|
|
267
276
|
token = config.get("token", None)
|
|
268
277
|
host = config.get("host", None)
|
|
269
278
|
user_token = config.get("user_token", None)
|
|
270
|
-
workspace_id = config.get("id",
|
|
271
|
-
workspace_name = config.get("name",
|
|
279
|
+
workspace_id = config.get("id", "")
|
|
280
|
+
workspace_name = config.get("name", "")
|
|
272
281
|
try:
|
|
273
282
|
if not token or not host or not workspace_id or not user_token:
|
|
274
283
|
yes = click.confirm(
|
|
@@ -294,8 +303,17 @@ def run_agent(config: dict[str, Any], project: Project, dangerously_skip_permiss
|
|
|
294
303
|
)
|
|
295
304
|
return
|
|
296
305
|
|
|
306
|
+
# In print mode, always skip permissions to avoid interactive prompts
|
|
307
|
+
skip_permissions = dangerously_skip_permissions or (prompt is not None)
|
|
308
|
+
agent = TinybirdAgent(token, user_token, host, workspace_id, project, skip_permissions)
|
|
309
|
+
|
|
310
|
+
# Print mode: run once with the provided prompt and exit
|
|
311
|
+
if prompt:
|
|
312
|
+
agent.run(prompt, config, project)
|
|
313
|
+
return
|
|
314
|
+
|
|
315
|
+
# Interactive mode: show banner and enter interactive loop
|
|
297
316
|
display_banner()
|
|
298
|
-
agent = TinybirdAgent(token, user_token, host, workspace_id, project, dangerously_skip_permissions)
|
|
299
317
|
click.echo()
|
|
300
318
|
click.echo(FeedbackManager.info(message="Describe what you want to create and I'll help you build it"))
|
|
301
319
|
click.echo(FeedbackManager.info(message="Run /help for more commands"))
|
|
@@ -420,17 +438,31 @@ def mock_data(
|
|
|
420
438
|
)
|
|
421
439
|
|
|
422
440
|
|
|
423
|
-
def analyze_fixture(config: dict[str, Any], fixture_path: str) -> dict[str, Any]:
|
|
441
|
+
def analyze_fixture(config: dict[str, Any], fixture_path: str, format: str = "json") -> dict[str, Any]:
|
|
424
442
|
local_client = get_tinybird_local_client(config, test=False, silent=True)
|
|
425
|
-
meta, _data = _analyze(fixture_path, local_client,
|
|
443
|
+
meta, _data = _analyze(fixture_path, local_client, format)
|
|
426
444
|
return meta
|
|
427
445
|
|
|
428
446
|
|
|
429
|
-
def execute_cloud_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> str:
|
|
447
|
+
def execute_cloud_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> dict[str, Any]:
|
|
430
448
|
client = _get_tb_client(config["token"], config["host"])
|
|
431
449
|
return client.query(sql=query, pipeline=pipe_name)
|
|
432
450
|
|
|
433
451
|
|
|
434
|
-
def execute_local_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> str:
|
|
452
|
+
def execute_local_query(config: dict[str, Any], query: str, pipe_name: Optional[str] = None) -> dict[str, Any]:
|
|
435
453
|
local_client = get_tinybird_local_client(config, test=False, silent=True)
|
|
436
454
|
return local_client.query(sql=query, pipeline=pipe_name)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def request_endpoint_cloud(
|
|
458
|
+
config: dict[str, Any], endpoint_name: str, params: Optional[dict[str, str]] = None
|
|
459
|
+
) -> dict[str, Any]:
|
|
460
|
+
client = _get_tb_client(config["token"], config["host"])
|
|
461
|
+
return client.pipe_data(endpoint_name, format="json", params=params)
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def request_endpoint_local(
|
|
465
|
+
config: dict[str, Any], endpoint_name: str, params: Optional[dict[str, str]] = None
|
|
466
|
+
) -> dict[str, Any]:
|
|
467
|
+
local_client = get_tinybird_local_client(config, test=False, silent=True)
|
|
468
|
+
return local_client.pipe_data(endpoint_name, format="json", params=params)
|
|
@@ -147,3 +147,240 @@ def get_resource_type(path: Path) -> str:
|
|
|
147
147
|
elif path.suffix.lower() == ".connection":
|
|
148
148
|
return "connection"
|
|
149
149
|
return "unknown"
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
endpoint_optimization_instructions = """
|
|
153
|
+
<endpoint_optimization_instructions>
|
|
154
|
+
## Endpoint Optimization Instructions
|
|
155
|
+
### Step 1: Identify Performance Issues
|
|
156
|
+
1. Analyze the endpoint's query performance metrics
|
|
157
|
+
2. Look for endpoints with high latency or excessive data scanning
|
|
158
|
+
3. Check read_bytes/write_bytes ratios to detect inefficient operations
|
|
159
|
+
|
|
160
|
+
### Step 2: Apply the 5-Question Diagnostic Framework
|
|
161
|
+
|
|
162
|
+
#### Question 1: Are you aggregating or transforming data at query time?
|
|
163
|
+
**Detection:**
|
|
164
|
+
- Look for `count()`, `sum()`, `avg()`, or data type casting in published API endpoints
|
|
165
|
+
- Check if the same calculations are performed on every request
|
|
166
|
+
|
|
167
|
+
**Fix:**
|
|
168
|
+
- Create Materialized Views to pre-aggregate data at ingestion time
|
|
169
|
+
- Move transformations from query time to ingestion time
|
|
170
|
+
- Example transformation:
|
|
171
|
+
```sql
|
|
172
|
+
-- Before (in endpoint)
|
|
173
|
+
SELECT date, count(*) as daily_count
|
|
174
|
+
FROM events
|
|
175
|
+
GROUP BY date
|
|
176
|
+
|
|
177
|
+
-- After (in Materialized View)
|
|
178
|
+
ENGINE "AggregatingMergeTree"
|
|
179
|
+
ENGINE_PARTITION_KEY "toYYYYMM(date)"
|
|
180
|
+
ENGINE_SORTING_KEY "date"
|
|
181
|
+
AS SELECT
|
|
182
|
+
date,
|
|
183
|
+
count(*) as daily_count
|
|
184
|
+
FROM events
|
|
185
|
+
GROUP BY date
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Question 2: Are you filtering by fields in the sorting key?
|
|
189
|
+
**Detection:**
|
|
190
|
+
- Examine WHERE clauses in queries
|
|
191
|
+
- Check if filtered columns are part of the sorting key
|
|
192
|
+
- Look for filters on partition keys instead of sorting keys
|
|
193
|
+
|
|
194
|
+
**Fix:**
|
|
195
|
+
- Ensure sorting key includes frequently filtered columns
|
|
196
|
+
- Order sorting key columns by selectivity (most selective first)
|
|
197
|
+
- Guidelines:
|
|
198
|
+
- Use 3-5 columns in sorting key
|
|
199
|
+
- Place `customer_id` or tenant identifiers first for multi-tenant apps
|
|
200
|
+
- Avoid `timestamp` as the first sorting key element
|
|
201
|
+
- Never use partition key for filtering
|
|
202
|
+
|
|
203
|
+
**Example Fix:**
|
|
204
|
+
```sql
|
|
205
|
+
-- Before
|
|
206
|
+
ENGINE_SORTING_KEY "timestamp, customer_id"
|
|
207
|
+
|
|
208
|
+
-- After (better for multi-tenant filtering)
|
|
209
|
+
ENGINE_SORTING_KEY "customer_id, timestamp"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### Question 3: Are you using the best data types?
|
|
213
|
+
**Detection:**
|
|
214
|
+
- Scan for overly large data types:
|
|
215
|
+
- String where UUID would work
|
|
216
|
+
- Int64 where UInt32 would suffice
|
|
217
|
+
- DateTime with unnecessary precision
|
|
218
|
+
- Nullable columns that could have defaults
|
|
219
|
+
|
|
220
|
+
**Fix:**
|
|
221
|
+
- Downsize data types:
|
|
222
|
+
```sql
|
|
223
|
+
-- Before
|
|
224
|
+
id String,
|
|
225
|
+
count Int64,
|
|
226
|
+
created_at DateTime64(3),
|
|
227
|
+
status Nullable(String)
|
|
228
|
+
|
|
229
|
+
-- After
|
|
230
|
+
id UUID,
|
|
231
|
+
count UInt32,
|
|
232
|
+
created_at DateTime,
|
|
233
|
+
status LowCardinality(String) DEFAULT 'pending'
|
|
234
|
+
```
|
|
235
|
+
- Use `LowCardinality()` for strings with <100k unique values
|
|
236
|
+
- Replace Nullable with default values using `coalesce()`
|
|
237
|
+
|
|
238
|
+
#### Question 4: Are you doing complex operations early in the pipeline?
|
|
239
|
+
**Detection:**
|
|
240
|
+
- Look for JOINs or aggregations before filters
|
|
241
|
+
- Check operation order in multi-node pipes
|
|
242
|
+
|
|
243
|
+
**Fix:**
|
|
244
|
+
- Reorder operations: Filter → Simple transforms → Complex operations
|
|
245
|
+
- Example:
|
|
246
|
+
```sql
|
|
247
|
+
-- Before
|
|
248
|
+
SELECT * FROM (
|
|
249
|
+
SELECT a.*, b.name
|
|
250
|
+
FROM events a
|
|
251
|
+
JOIN users b ON a.user_id = b.id
|
|
252
|
+
) WHERE date >= today() - 7
|
|
253
|
+
|
|
254
|
+
-- After
|
|
255
|
+
SELECT a.*, b.name
|
|
256
|
+
FROM (
|
|
257
|
+
SELECT * FROM events
|
|
258
|
+
WHERE date >= today() - 7
|
|
259
|
+
) a
|
|
260
|
+
JOIN users b ON a.user_id = b.id
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### Question 5: Are you joining two or more data sources?
|
|
264
|
+
**Detection:**
|
|
265
|
+
- Identify JOINs in queries
|
|
266
|
+
- Check read_bytes/write_bytes ratio in Materialized Views
|
|
267
|
+
- Look for full table scans on joined tables
|
|
268
|
+
|
|
269
|
+
**Fix Options:**
|
|
270
|
+
1. Replace JOIN with subquery:
|
|
271
|
+
```sql
|
|
272
|
+
-- Before
|
|
273
|
+
SELECT e.*, u.name
|
|
274
|
+
FROM events e
|
|
275
|
+
JOIN users u ON e.user_id = u.id
|
|
276
|
+
|
|
277
|
+
-- After
|
|
278
|
+
SELECT e.*,
|
|
279
|
+
(SELECT name FROM users WHERE id = e.user_id) as name
|
|
280
|
+
FROM events e
|
|
281
|
+
WHERE user_id IN (SELECT id FROM users)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
2. Optimize Materialized View JOINs:
|
|
285
|
+
```sql
|
|
286
|
+
-- Before (inefficient)
|
|
287
|
+
SELECT a.id, a.value, b.value
|
|
288
|
+
FROM a
|
|
289
|
+
LEFT JOIN b USING id
|
|
290
|
+
|
|
291
|
+
-- After (optimized)
|
|
292
|
+
SELECT a.id, a.value, b.value
|
|
293
|
+
FROM a
|
|
294
|
+
LEFT JOIN (
|
|
295
|
+
SELECT id, value
|
|
296
|
+
FROM b
|
|
297
|
+
WHERE b.id IN (SELECT id FROM a)
|
|
298
|
+
) b USING id
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Step 3: Implementation Actions
|
|
302
|
+
|
|
303
|
+
#### For Schema Changes:
|
|
304
|
+
1. Update the datasource schema
|
|
305
|
+
2. Update the sorting keys and data types
|
|
306
|
+
3. Update dependent pipes and endpoints
|
|
307
|
+
|
|
308
|
+
#### For Query Optimizations:
|
|
309
|
+
1. Create Materialized Views for repeated aggregations
|
|
310
|
+
2. Rewrite queries following best practices
|
|
311
|
+
3. Test performance improvements
|
|
312
|
+
|
|
313
|
+
#### For JOIN Optimizations:
|
|
314
|
+
1. Evaluate if JOIN is necessary
|
|
315
|
+
2. Consider denormalization strategies
|
|
316
|
+
3. Use Copy Pipes for historical data recalculation
|
|
317
|
+
4. Implement filtered JOINs in Materialized Views
|
|
318
|
+
|
|
319
|
+
#### In general:
|
|
320
|
+
1. If you need to iterate an existing resource, do not create a new iteration, just update it with the needed changes.
|
|
321
|
+
|
|
322
|
+
## Monitoring and Validation
|
|
323
|
+
|
|
324
|
+
### Monitoring:
|
|
325
|
+
1. Set up alerts for endpoints exceeding latency thresholds
|
|
326
|
+
2. Review of tinybird.pipe_stats_rt (realtime stats of last 24h) and tinybird.pipe_stats (historical stats aggregated by day)
|
|
327
|
+
3. Track processed data patterns over time
|
|
328
|
+
4. Monitor for query pattern changes
|
|
329
|
+
|
|
330
|
+
### Success Metrics:
|
|
331
|
+
- Reduced query latency
|
|
332
|
+
- Lower data scanning (read_bytes)
|
|
333
|
+
- Improved read_bytes/write_bytes ratio
|
|
334
|
+
- Consistent sub-second API response times
|
|
335
|
+
|
|
336
|
+
## Code Templates
|
|
337
|
+
|
|
338
|
+
### Materialized View Template:
|
|
339
|
+
```sql
|
|
340
|
+
NODE materialized_view_name
|
|
341
|
+
SQL >
|
|
342
|
+
SELECT
|
|
343
|
+
-- Pre-aggregated fields
|
|
344
|
+
toDate(timestamp) as date,
|
|
345
|
+
customer_id,
|
|
346
|
+
count(*) as event_count,
|
|
347
|
+
sum(amount) as total_amount
|
|
348
|
+
FROM source_table
|
|
349
|
+
GROUP BY date, customer_id
|
|
350
|
+
|
|
351
|
+
TYPE materialized
|
|
352
|
+
DATASOURCE mv_datasource_name
|
|
353
|
+
ENGINE "AggregatingMergeTree"
|
|
354
|
+
ENGINE_PARTITION_KEY "toYYYYMM(date)"
|
|
355
|
+
ENGINE_SORTING_KEY "customer_id, date"
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Optimized Query Template:
|
|
359
|
+
```sql
|
|
360
|
+
NODE endpoint_query
|
|
361
|
+
SQL >
|
|
362
|
+
-- Step 1: Filter early
|
|
363
|
+
WITH filtered_data AS (
|
|
364
|
+
SELECT * FROM events
|
|
365
|
+
WHERE customer_id = {{ String(customer_id) }}
|
|
366
|
+
AND date >= {{ Date(start_date) }}
|
|
367
|
+
AND date <= {{ Date(end_date) }}
|
|
368
|
+
)
|
|
369
|
+
-- Step 2: Simple operations
|
|
370
|
+
SELECT
|
|
371
|
+
date,
|
|
372
|
+
sum(amount) as daily_total
|
|
373
|
+
FROM filtered_data
|
|
374
|
+
GROUP BY date
|
|
375
|
+
ORDER BY date DESC
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Best Practices Summary
|
|
379
|
+
|
|
380
|
+
1. **Think ingestion-time, not query-time** - Move computations upstream
|
|
381
|
+
2. **Index smartly** - Sorting keys should match filter patterns
|
|
382
|
+
3. **Size appropriately** - Use the smallest viable data types
|
|
383
|
+
4. **Filter first** - Reduce data before complex operations
|
|
384
|
+
5. **JOIN carefully** - Consider alternatives and optimize when necessary
|
|
385
|
+
</endpoint_optimization_instructions>
|
|
386
|
+
"""
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from urllib.parse import urlparse
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from pydantic_ai import RunContext
|
|
7
|
+
|
|
8
|
+
from tinybird.tb.modules.agent.utils import TinybirdAgentContext
|
|
9
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def analyze_file(ctx: RunContext[TinybirdAgentContext], fixture_pathname: str):
|
|
13
|
+
"""Analyze a fixture data file present in the project folder
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
fixture_pathname (str): a path or an external url to a fixture file. Required.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
str: The content of the fixture data file.
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
ctx.deps.thinking_animation.stop()
|
|
23
|
+
click.echo(FeedbackManager.highlight(message=f"» Analyzing {fixture_pathname}..."))
|
|
24
|
+
fixture_path = Path(ctx.deps.folder) / fixture_pathname.lstrip("/")
|
|
25
|
+
|
|
26
|
+
if not fixture_path.exists():
|
|
27
|
+
click.echo(FeedbackManager.error(message=f"No fixture data found for {fixture_pathname}."))
|
|
28
|
+
ctx.deps.thinking_animation.start()
|
|
29
|
+
return f"No fixture data found for {fixture_pathname}. Please check the path of the fixture and try again."
|
|
30
|
+
|
|
31
|
+
fixture_extension = fixture_path.suffix.lstrip(".")
|
|
32
|
+
response = ctx.deps.analyze_fixture(fixture_path=str(fixture_path), format=fixture_extension)
|
|
33
|
+
click.echo(FeedbackManager.success(message="✓ Done!\n"))
|
|
34
|
+
ctx.deps.thinking_animation.start()
|
|
35
|
+
# limit content to first 10 rows
|
|
36
|
+
data = response["preview"]["data"][:10]
|
|
37
|
+
columns = response["analysis"]["columns"]
|
|
38
|
+
|
|
39
|
+
return f"#Result of analysis of {fixture_pathname}:\n##Columns:\n{json.dumps(columns)}\n##Data sample:\n{json.dumps(data)}"
|
|
40
|
+
except Exception as e:
|
|
41
|
+
ctx.deps.thinking_animation.stop()
|
|
42
|
+
click.echo(FeedbackManager.error(message=f"Error analyzing {fixture_pathname}: {e}"))
|
|
43
|
+
ctx.deps.thinking_animation.start()
|
|
44
|
+
return f"Error analyzing {fixture_pathname}: {e}"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def analyze_url(ctx: RunContext[TinybirdAgentContext], fixture_url: str):
|
|
48
|
+
"""Analyze a fixture file present in an external url
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
fixture_url (str): an external url to a fixture file. Required.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
str: The analysis with the columns and the first 10 rows of the fixture data file.
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
ctx.deps.thinking_animation.stop()
|
|
58
|
+
is_url = urlparse(fixture_url).scheme in ("http", "https")
|
|
59
|
+
click.echo(FeedbackManager.highlight(message=f"» Analyzing {fixture_url}..."))
|
|
60
|
+
if not is_url:
|
|
61
|
+
click.echo(FeedbackManager.error(message=f"{fixture_url} is not a valid url."))
|
|
62
|
+
ctx.deps.thinking_animation.start()
|
|
63
|
+
return f"{fixture_url} is not a valid url. Please check the url and try again."
|
|
64
|
+
|
|
65
|
+
fixture_extension = fixture_url.split(".")[-1]
|
|
66
|
+
|
|
67
|
+
response = ctx.deps.analyze_fixture(fixture_path=fixture_url, format=fixture_extension)
|
|
68
|
+
click.echo(FeedbackManager.success(message="✓ Done!\n"))
|
|
69
|
+
ctx.deps.thinking_animation.start()
|
|
70
|
+
# limit content to first 10 rows
|
|
71
|
+
data = response["preview"]["data"][:10]
|
|
72
|
+
columns = response["analysis"]["columns"]
|
|
73
|
+
|
|
74
|
+
return f"#Result of analysis of URL {fixture_url}:\n##Columns:\n{json.dumps(columns)}\n##Data sample:\n{json.dumps(data)}"
|
|
75
|
+
except Exception as e:
|
|
76
|
+
ctx.deps.thinking_animation.stop()
|
|
77
|
+
click.echo(FeedbackManager.error(message=f"Error analyzing {fixture_url}: {e}"))
|
|
78
|
+
ctx.deps.thinking_animation.start()
|
|
79
|
+
return f"Error analyzing {fixture_url}: {e}"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from pydantic_ai import RunContext
|
|
3
|
+
|
|
4
|
+
from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_confirmation, show_input
|
|
5
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def append_file(ctx: RunContext[TinybirdAgentContext], datasource_name: str, fixture_pathname: str) -> str:
|
|
9
|
+
"""Append existing fixture to a datasource
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
datasource_name: Name of the datasource to append fixture to
|
|
13
|
+
fixture_pathname: Path to the fixture file to append
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
str: Message indicating the success or failure of the appending
|
|
17
|
+
"""
|
|
18
|
+
try:
|
|
19
|
+
ctx.deps.thinking_animation.stop()
|
|
20
|
+
confirmation = show_confirmation(
|
|
21
|
+
title=f"Append fixture {fixture_pathname} to datasource {datasource_name}?",
|
|
22
|
+
skip_confirmation=ctx.deps.dangerously_skip_permissions,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if confirmation == "review":
|
|
26
|
+
click.echo()
|
|
27
|
+
feedback = show_input(ctx.deps.workspace_name)
|
|
28
|
+
ctx.deps.thinking_animation.start()
|
|
29
|
+
return (
|
|
30
|
+
f"User did not confirm appending {fixture_pathname} fixture and gave the following feedback: {feedback}"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if confirmation == "cancel":
|
|
34
|
+
ctx.deps.thinking_animation.start()
|
|
35
|
+
return f"User rejected appending {fixture_pathname} fixture. Skip this step"
|
|
36
|
+
|
|
37
|
+
ctx.deps.thinking_animation.stop()
|
|
38
|
+
click.echo(FeedbackManager.highlight(message=f"\n» Appending {fixture_pathname} to {datasource_name}..."))
|
|
39
|
+
ctx.deps.append_data(datasource_name=datasource_name, path=fixture_pathname)
|
|
40
|
+
click.echo(FeedbackManager.success(message=f"✓ Data appended to {datasource_name}"))
|
|
41
|
+
ctx.deps.thinking_animation.start()
|
|
42
|
+
return f"Data appended to {datasource_name}"
|
|
43
|
+
except Exception as e:
|
|
44
|
+
ctx.deps.thinking_animation.stop()
|
|
45
|
+
click.echo(FeedbackManager.error(message=e))
|
|
46
|
+
ctx.deps.thinking_animation.start()
|
|
47
|
+
return f"Error appending fixture {fixture_pathname} to {datasource_name}: {e}"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def append_url(ctx: RunContext[TinybirdAgentContext], datasource_name: str, fixture_url: str) -> str:
|
|
51
|
+
"""Append existing fixture to a datasource
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
datasource_name: Name of the datasource to append fixture to
|
|
55
|
+
fixture_url: external url to the fixture file to append
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
str: Message indicating the success or failure of the appending
|
|
59
|
+
"""
|
|
60
|
+
try:
|
|
61
|
+
ctx.deps.thinking_animation.stop()
|
|
62
|
+
confirmation = show_confirmation(
|
|
63
|
+
title=f"Append URL {fixture_url} to datasource {datasource_name}?",
|
|
64
|
+
skip_confirmation=ctx.deps.dangerously_skip_permissions,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if confirmation == "review":
|
|
68
|
+
click.echo()
|
|
69
|
+
feedback = show_input(ctx.deps.workspace_name)
|
|
70
|
+
ctx.deps.thinking_animation.start()
|
|
71
|
+
return f"User did not confirm appending URL {fixture_url} and gave the following feedback: {feedback}"
|
|
72
|
+
|
|
73
|
+
if confirmation == "cancel":
|
|
74
|
+
ctx.deps.thinking_animation.start()
|
|
75
|
+
return f"User rejected appending URL {fixture_url}. Skip this step"
|
|
76
|
+
|
|
77
|
+
ctx.deps.thinking_animation.stop()
|
|
78
|
+
click.echo(FeedbackManager.highlight(message=f"\n» Appending {fixture_url} to {datasource_name}..."))
|
|
79
|
+
ctx.deps.append_data(datasource_name=datasource_name, path=fixture_url)
|
|
80
|
+
click.echo(FeedbackManager.success(message=f"✓ Data appended to {datasource_name}"))
|
|
81
|
+
ctx.deps.thinking_animation.start()
|
|
82
|
+
return f"Data appended to {datasource_name}"
|
|
83
|
+
except Exception as e:
|
|
84
|
+
ctx.deps.thinking_animation.stop()
|
|
85
|
+
click.echo(FeedbackManager.error(message=e))
|
|
86
|
+
ctx.deps.thinking_animation.start()
|
|
87
|
+
return f"Error appending URL {fixture_url} to {datasource_name}: {e}"
|
{tinybird-0.0.1.dev252 → tinybird-0.0.1.dev254}/tinybird/tb/modules/agent/tools/deploy_check.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import click
|
|
2
2
|
from pydantic_ai import RunContext
|
|
3
3
|
|
|
4
|
-
from tinybird.tb.modules.agent.utils import TinybirdAgentContext
|
|
4
|
+
from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_confirmation, show_input
|
|
5
5
|
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
6
6
|
|
|
7
7
|
|
|
@@ -9,6 +9,21 @@ def deploy_check(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
|
9
9
|
"""Check that project can be deployed"""
|
|
10
10
|
try:
|
|
11
11
|
ctx.deps.thinking_animation.stop()
|
|
12
|
+
confirmation = show_confirmation(
|
|
13
|
+
title="Check that project can be deployed?",
|
|
14
|
+
skip_confirmation=ctx.deps.dangerously_skip_permissions,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if confirmation == "review":
|
|
18
|
+
click.echo()
|
|
19
|
+
feedback = show_input(ctx.deps.workspace_name)
|
|
20
|
+
ctx.deps.thinking_animation.start()
|
|
21
|
+
return f"User did not confirm deployment check and gave the following feedback: {feedback}"
|
|
22
|
+
|
|
23
|
+
if confirmation == "cancel":
|
|
24
|
+
ctx.deps.thinking_animation.start()
|
|
25
|
+
return "User cancelled deployment check. Stop deployment check."
|
|
26
|
+
|
|
12
27
|
ctx.deps.deploy_check_project()
|
|
13
28
|
ctx.deps.thinking_animation.start()
|
|
14
29
|
return "Project can be deployed"
|