tinybird 0.0.1.dev256__tar.gz → 0.0.1.dev257__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.dev256 → tinybird-0.0.1.dev257}/PKG-INFO +2 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datafile/common.py +2 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/__cli__.py +2 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/agent.py +150 -216
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/prompts.py +154 -6
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/append.py +31 -21
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/build.py +1 -1
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/create_datafile.py +57 -6
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/deploy.py +1 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/diff_resource.py +1 -3
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/execute_query.py +1 -1
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +1 -2
- tinybird-0.0.1.dev257/tinybird/tb/modules/agent/tools/get_openapi_definition.py +53 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/mock.py +17 -9
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/plan.py +2 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/request_endpoint.py +5 -4
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/utils.py +6 -3
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/cli.py +9 -7
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/PKG-INFO +2 -2
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/requires.txt +1 -1
- tinybird-0.0.1.dev256/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -39
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/setup.cfg +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/__cli__.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/check_pypi.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/client.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/config.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/connectors.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/context.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/datatypes.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/git_settings.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/prompts.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/sql.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/sql_template.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/sql_toolset.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/syncasync.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/cli.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/client.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/config.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/__init__.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/animations.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/banner.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/memory.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/models.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/explore.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/agent/tools/preview_datafile.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/build.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/config.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/create.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/deployment_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/dev_server.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/info.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/job.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/local.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/login.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/mock.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/mock_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/open.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/project.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/shell.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/table.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/test.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/token.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird/tornado_template.py +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-0.0.1.dev256 → tinybird-0.0.1.dev257}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version: 0.0.1.
|
|
3
|
+
Version: 0.0.1.dev257
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -21,7 +21,7 @@ Requires-Dist: GitPython~=3.1.32
|
|
|
21
21
|
Requires-Dist: humanfriendly~=8.2
|
|
22
22
|
Requires-Dist: prompt_toolkit==3.0.48
|
|
23
23
|
Requires-Dist: pydantic~=2.11.7
|
|
24
|
-
Requires-Dist: pydantic-ai-slim[anthropic]~=0.
|
|
24
|
+
Requires-Dist: pydantic-ai-slim[anthropic]~=0.4.2
|
|
25
25
|
Requires-Dist: pyperclip==1.8.2
|
|
26
26
|
Requires-Dist: pyyaml<6.1,>=6.0
|
|
27
27
|
Requires-Dist: requests<3,>=2.28.1
|
|
@@ -1744,6 +1744,8 @@ def parse(
|
|
|
1744
1744
|
def _f(*args: str, **kwargs: Any):
|
|
1745
1745
|
__init_engine(f"ENGINE_{v}".upper())
|
|
1746
1746
|
engine_arg = eval_var(_unquote((" ".join(args)).strip()), skip=skip_eval)
|
|
1747
|
+
if v.lower() == "ttl" and not engine_arg:
|
|
1748
|
+
return
|
|
1747
1749
|
parser_state.current_node["engine"]["args"].append((v, engine_arg))
|
|
1748
1750
|
|
|
1749
1751
|
return _f
|
|
@@ -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.dev257'
|
|
8
|
+
__revision__ = '249ae8d'
|
|
@@ -1,41 +1,23 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import shlex
|
|
2
3
|
import subprocess
|
|
3
4
|
import sys
|
|
4
|
-
from datetime import datetime
|
|
5
5
|
from functools import partial
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Any, Optional
|
|
8
8
|
|
|
9
9
|
import click
|
|
10
|
-
|
|
10
|
+
import humanfriendly
|
|
11
|
+
from pydantic_ai import Agent, RunContext, Tool
|
|
12
|
+
from pydantic_ai.agent import AgentRunResult
|
|
11
13
|
from pydantic_ai.messages import ModelMessage
|
|
12
14
|
|
|
13
|
-
from tinybird.prompts import (
|
|
14
|
-
connection_instructions,
|
|
15
|
-
copy_pipe_instructions,
|
|
16
|
-
datasource_example,
|
|
17
|
-
datasource_instructions,
|
|
18
|
-
gcs_connection_example,
|
|
19
|
-
kafka_connection_example,
|
|
20
|
-
materialized_pipe_instructions,
|
|
21
|
-
pipe_example,
|
|
22
|
-
pipe_instructions,
|
|
23
|
-
s3_connection_example,
|
|
24
|
-
sink_pipe_instructions,
|
|
25
|
-
)
|
|
26
15
|
from tinybird.tb.client import TinyB
|
|
27
16
|
from tinybird.tb.modules.agent.animations import ThinkingAnimation
|
|
28
17
|
from tinybird.tb.modules.agent.banner import display_banner
|
|
29
18
|
from tinybird.tb.modules.agent.memory import clear_history, clear_messages, load_messages, save_messages
|
|
30
19
|
from tinybird.tb.modules.agent.models import create_model, model_costs
|
|
31
|
-
from tinybird.tb.modules.agent.prompts import
|
|
32
|
-
datafile_instructions,
|
|
33
|
-
endpoint_optimization_instructions,
|
|
34
|
-
plan_instructions,
|
|
35
|
-
resources_prompt,
|
|
36
|
-
sql_agent_instructions,
|
|
37
|
-
sql_instructions,
|
|
38
|
-
)
|
|
20
|
+
from tinybird.tb.modules.agent.prompts import agent_system_prompt, resources_prompt
|
|
39
21
|
from tinybird.tb.modules.agent.tools.analyze import analyze_file, analyze_url
|
|
40
22
|
from tinybird.tb.modules.agent.tools.append import append_file, append_url
|
|
41
23
|
from tinybird.tb.modules.agent.tools.build import build
|
|
@@ -52,7 +34,7 @@ from tinybird.tb.modules.agent.tools.preview_datafile import preview_datafile
|
|
|
52
34
|
from tinybird.tb.modules.agent.tools.request_endpoint import request_endpoint
|
|
53
35
|
from tinybird.tb.modules.agent.utils import TinybirdAgentContext, show_input
|
|
54
36
|
from tinybird.tb.modules.build_common import process as build_process
|
|
55
|
-
from tinybird.tb.modules.common import _analyze, _get_tb_client
|
|
37
|
+
from tinybird.tb.modules.common import _analyze, _get_tb_client, echo_safe_humanfriendly_tables_format_pretty_table
|
|
56
38
|
from tinybird.tb.modules.config import CLIConfig
|
|
57
39
|
from tinybird.tb.modules.deployment_common import create_deployment
|
|
58
40
|
from tinybird.tb.modules.exceptions import CLIBuildException, CLIDeploymentException, CLIMockException
|
|
@@ -72,141 +54,21 @@ class TinybirdAgent:
|
|
|
72
54
|
workspace_id: str,
|
|
73
55
|
project: Project,
|
|
74
56
|
dangerously_skip_permissions: bool,
|
|
57
|
+
prompt_mode: bool,
|
|
75
58
|
):
|
|
76
59
|
self.token = token
|
|
77
60
|
self.user_token = user_token
|
|
78
61
|
self.host = host
|
|
79
|
-
self.dangerously_skip_permissions = dangerously_skip_permissions
|
|
62
|
+
self.dangerously_skip_permissions = dangerously_skip_permissions or prompt_mode
|
|
80
63
|
self.project = project
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
if prompt_mode:
|
|
65
|
+
self.messages: list[ModelMessage] = load_messages()[-5:]
|
|
66
|
+
else:
|
|
67
|
+
self.messages = []
|
|
83
68
|
self.agent = Agent(
|
|
84
69
|
model=create_model(user_token, host, workspace_id),
|
|
85
70
|
deps_type=TinybirdAgentContext,
|
|
86
|
-
system_prompt=
|
|
87
|
-
You are a Tinybird Code, an agentic CLI that can help users to work with Tinybird.
|
|
88
|
-
|
|
89
|
-
You are an interactive CLI tool that helps users with data engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
90
|
-
|
|
91
|
-
# Tone and style
|
|
92
|
-
You should be concise, direct, and to the point.
|
|
93
|
-
Remember that your output will be displayed on a command line interface. Your responses can use Github-flavored markdown for formatting. Do not use emojis.
|
|
94
|
-
Output text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like Bash or code comments as means to communicate with the user during the session.
|
|
95
|
-
If you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.
|
|
96
|
-
IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.
|
|
97
|
-
IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.
|
|
98
|
-
IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is <answer>.", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". Here are some examples to demonstrate appropriate verbosity:
|
|
99
|
-
|
|
100
|
-
# Proactiveness
|
|
101
|
-
You are allowed to be proactive, but only when the user asks you to do something. You should strive to strike a balance between:
|
|
102
|
-
Doing the right thing when asked, including taking actions and follow-up actions
|
|
103
|
-
Not surprising the user with actions you take without asking
|
|
104
|
-
For example, if the user asks you how to approach something, you should do your best to answer their question first, and not immediately jump into taking actions.
|
|
105
|
-
Do not add additional code explanation summary unless requested by the user. After working on a file, just stop, rather than providing an explanation of what you did.
|
|
106
|
-
|
|
107
|
-
# Code style
|
|
108
|
-
IMPORTANT: DO NOT ADD ANY COMMENTS unless asked by the user.
|
|
109
|
-
|
|
110
|
-
# Tools
|
|
111
|
-
You have access to the following tools:
|
|
112
|
-
1. `preview_datafile` - Preview the content of a datafile (datasource, endpoint, materialized, sink, copy, connection).
|
|
113
|
-
2. `create_datafile` - Create a file in the project folder. Confirmation will be asked by the tool before creating the file.
|
|
114
|
-
3. `plan` - Plan the creation or update of resources.
|
|
115
|
-
4. `build` - Build the project.
|
|
116
|
-
5. `deploy` - Deploy the project to Tinybird Cloud.
|
|
117
|
-
6. `deploy_check` - Check if the project can be deployed to Tinybird Cloud before deploying it.
|
|
118
|
-
7. `mock` - Create mock data for a landing datasource.
|
|
119
|
-
8. `analyze_file` - Analyze the content of a fixture file present in the project folder.
|
|
120
|
-
9. `analyze_url` - Analyze the content of an external url.
|
|
121
|
-
9. `append_file` - Append a file present in the project to a datasource.
|
|
122
|
-
10. `append_url` - Append an external url to a datasource.
|
|
123
|
-
11. `get_endpoint_stats` - Get metrics of the requests to an endpoint.
|
|
124
|
-
12. `get_openapi_definition` - Get the OpenAPI definition for all endpoints that are built/deployed to Tinybird Cloud or Local.
|
|
125
|
-
13. `execute_query` - Execute a query against Tinybird Cloud or Local.
|
|
126
|
-
13. `request_endpoint` - Request an endpoint against Tinybird Cloud or Local.
|
|
127
|
-
14. `diff_resource` - Diff the content of a resource in Tinybird Cloud vs Tinybird Local vs Project local file.
|
|
128
|
-
|
|
129
|
-
# When creating or updating datafiles:
|
|
130
|
-
1. Use `plan` tool to plan the creation or update of resources.
|
|
131
|
-
2. If the user confirms the plan, go from 3 to 7 steps until all the resources are created, updated or skipped.
|
|
132
|
-
3. Use `preview_datafile` tool to preview the content of a datafile.
|
|
133
|
-
4. Without asking, use the `create_datafile` tool to create the datafile, because it will ask for confirmation before creating the file.
|
|
134
|
-
5. Check the result of the `create_datafile` tool to see if the datafile was created successfully.
|
|
135
|
-
6. If the datafile was created successfully, report the result to the user.
|
|
136
|
-
7. If the datafile was not created, finish the process and just wait for a new user prompt.
|
|
137
|
-
8. If the datafile was created successfully, but the built failed, try to fix the error and repeat the process.
|
|
138
|
-
|
|
139
|
-
# When creating a landing datasource given a .ndjson file:
|
|
140
|
-
- If the user does not specify anything about the desired schema, create a schema like this:
|
|
141
|
-
SCHEMA >
|
|
142
|
-
`data` String `json:$`
|
|
143
|
-
|
|
144
|
-
- Use always json paths with .ndjson files.
|
|
145
|
-
|
|
146
|
-
# When user wants to optimize an endpoint:
|
|
147
|
-
{endpoint_optimization_instructions}
|
|
148
|
-
|
|
149
|
-
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.
|
|
150
|
-
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.
|
|
151
|
-
|
|
152
|
-
# Using deployment tools:
|
|
153
|
-
- Use `deploy_check` tool to check if the project can be deployed to Tinybird Cloud before deploying it.
|
|
154
|
-
- Use `deploy` tool to deploy the project to Tinybird Cloud.
|
|
155
|
-
- Only use deployment tools if user explicitly asks for it.
|
|
156
|
-
|
|
157
|
-
# When planning the creation or update of resources:
|
|
158
|
-
{plan_instructions}
|
|
159
|
-
{datafile_instructions}
|
|
160
|
-
|
|
161
|
-
# Working with datasource files:
|
|
162
|
-
{datasource_instructions}
|
|
163
|
-
{datasource_example}
|
|
164
|
-
|
|
165
|
-
# Working with any type of pipe file:
|
|
166
|
-
{pipe_instructions}
|
|
167
|
-
{pipe_example}
|
|
168
|
-
|
|
169
|
-
# Working with materialized pipe files:
|
|
170
|
-
{materialized_pipe_instructions}
|
|
171
|
-
|
|
172
|
-
# Working with sink pipe files:
|
|
173
|
-
{sink_pipe_instructions}
|
|
174
|
-
|
|
175
|
-
# Working with copy pipe files:
|
|
176
|
-
{copy_pipe_instructions}
|
|
177
|
-
|
|
178
|
-
# Working with SQL queries:
|
|
179
|
-
{sql_agent_instructions}
|
|
180
|
-
{sql_instructions}
|
|
181
|
-
|
|
182
|
-
# Working with connections files:
|
|
183
|
-
{connection_instructions}
|
|
184
|
-
|
|
185
|
-
# Connection examples:
|
|
186
|
-
Kafka: {kafka_connection_example}
|
|
187
|
-
S3: {s3_connection_example}
|
|
188
|
-
GCS: {gcs_connection_example}
|
|
189
|
-
|
|
190
|
-
# When executing a query or requesting/testing an endpoint:
|
|
191
|
-
- You need to be sure that the selected resource is updated to the last version in the environment you are working on.
|
|
192
|
-
- Use `diff_resource` tool to compare the content of the resource to compare the differences between environments.
|
|
193
|
-
- Project local file is the source of truth.
|
|
194
|
-
- If the resource is not present or updated to the last version in Tinybird Local, it means you need to build the project.
|
|
195
|
-
- If the resource is not present or updated to the last version in Tinybird Cloud, it means you need to deploy the project.
|
|
196
|
-
|
|
197
|
-
# How to use apppend tools:
|
|
198
|
-
- Use append as part of the creation of a new landing datasource if the user provided a file or an external url
|
|
199
|
-
- Use append if user explicitly asks for it
|
|
200
|
-
- Do not append data if user requests to test an endpoint
|
|
201
|
-
|
|
202
|
-
# How to use `mock` tool:
|
|
203
|
-
- Use `mock` tool as part of the creation of a new landing datasource if the user did not provided a file or an external url
|
|
204
|
-
- Use `mock` tool if user explicitly asks for it
|
|
205
|
-
- Do not use `mock` tool if user requests to test an endpoint.
|
|
206
|
-
|
|
207
|
-
# Info
|
|
208
|
-
Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
209
|
-
""",
|
|
71
|
+
system_prompt=agent_system_prompt,
|
|
210
72
|
tools=[
|
|
211
73
|
Tool(preview_datafile, docstring_format="google", require_parameter_descriptions=True, takes_ctx=False),
|
|
212
74
|
Tool(create_datafile, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
@@ -232,77 +94,131 @@ Today is {datetime.now().strftime("%Y-%m-%d")}
|
|
|
232
94
|
Tool(request_endpoint, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
233
95
|
Tool(diff_resource, docstring_format="google", require_parameter_descriptions=True, takes_ctx=True),
|
|
234
96
|
],
|
|
97
|
+
# history_processors=[self._keep_recent_messages],
|
|
235
98
|
)
|
|
236
99
|
|
|
237
|
-
|
|
100
|
+
@self.agent.instructions
|
|
101
|
+
def get_local_host(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
102
|
+
return f"Tinybird Local host: {ctx.deps.local_host}"
|
|
103
|
+
|
|
104
|
+
@self.agent.instructions
|
|
105
|
+
def get_cloud_host(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
106
|
+
return f"Tinybird Cloud host: {ctx.deps.host}"
|
|
107
|
+
|
|
108
|
+
@self.agent.instructions
|
|
109
|
+
def get_local_token(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
110
|
+
return f"Tinybird Local token: {ctx.deps.local_token}"
|
|
111
|
+
|
|
112
|
+
@self.agent.instructions
|
|
113
|
+
def get_cloud_token(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
114
|
+
return f"Tinybird Cloud token: {ctx.deps.token}"
|
|
115
|
+
|
|
116
|
+
@self.agent.instructions
|
|
117
|
+
def get_project_files(ctx: RunContext[TinybirdAgentContext]) -> str:
|
|
118
|
+
return resources_prompt(self.project)
|
|
119
|
+
|
|
120
|
+
self.thinking_animation = ThinkingAnimation()
|
|
121
|
+
|
|
122
|
+
def _keep_recent_messages(self, messages: list[ModelMessage]) -> list[ModelMessage]:
|
|
238
123
|
"""Keep only the last 5 messages to manage token usage."""
|
|
239
|
-
return
|
|
124
|
+
return messages[-5:] if len(messages) > 5 else messages
|
|
240
125
|
|
|
241
|
-
def
|
|
242
|
-
user_prompt = f"{user_prompt}\n\n{resources_prompt(project)}"
|
|
126
|
+
def _build_agent_deps(self, config: dict[str, Any]) -> TinybirdAgentContext:
|
|
243
127
|
client = TinyB(token=self.token, host=self.host)
|
|
128
|
+
project = self.project
|
|
244
129
|
folder = self.project.folder
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
130
|
+
local_client = get_tinybird_local_client(config, test=False, silent=False)
|
|
131
|
+
return TinybirdAgentContext(
|
|
132
|
+
# context does not support the whole client, so we need to pass only the functions we need
|
|
133
|
+
explore_data=client.explore_data,
|
|
134
|
+
build_project=partial(build_project, project=project, config=config),
|
|
135
|
+
deploy_project=partial(deploy_project, project=project, config=config),
|
|
136
|
+
deploy_check_project=partial(deploy_check_project, project=project, config=config),
|
|
137
|
+
mock_data=partial(mock_data, project=project, config=config),
|
|
138
|
+
append_data_local=partial(append_data_local, config=config),
|
|
139
|
+
append_data_cloud=partial(append_data_cloud, config=config),
|
|
140
|
+
analyze_fixture=partial(analyze_fixture, config=config),
|
|
141
|
+
execute_query_cloud=partial(execute_query_cloud, config=config),
|
|
142
|
+
execute_query_local=partial(execute_query_local, config=config),
|
|
143
|
+
request_endpoint_cloud=partial(request_endpoint_cloud, config=config),
|
|
144
|
+
request_endpoint_local=partial(request_endpoint_local, config=config),
|
|
145
|
+
get_datasource_datafile_cloud=partial(get_datasource_datafile_cloud, config=config),
|
|
146
|
+
get_datasource_datafile_local=partial(get_datasource_datafile_local, config=config),
|
|
147
|
+
get_pipe_datafile_cloud=partial(get_pipe_datafile_cloud, config=config),
|
|
148
|
+
get_pipe_datafile_local=partial(get_pipe_datafile_local, config=config),
|
|
149
|
+
get_connection_datafile_cloud=partial(get_connection_datafile_cloud, config=config),
|
|
150
|
+
get_connection_datafile_local=partial(get_connection_datafile_local, config=config),
|
|
151
|
+
get_project_files=project.get_project_files,
|
|
152
|
+
folder=folder,
|
|
153
|
+
thinking_animation=self.thinking_animation,
|
|
154
|
+
workspace_name=self.project.workspace_name,
|
|
155
|
+
dangerously_skip_permissions=self.dangerously_skip_permissions,
|
|
156
|
+
token=self.token,
|
|
157
|
+
user_token=self.user_token,
|
|
158
|
+
host=self.host,
|
|
159
|
+
local_host=local_client.host,
|
|
160
|
+
local_token=local_client.token,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
def run(self, user_prompt: str, config: dict[str, Any]) -> None:
|
|
164
|
+
user_prompt = f"{user_prompt}\n\n{resources_prompt(self.project)}"
|
|
165
|
+
self.thinking_animation.start()
|
|
248
166
|
result = self.agent.run_sync(
|
|
249
167
|
user_prompt,
|
|
250
|
-
deps=
|
|
251
|
-
# context does not support the whole client, so we need to pass only the functions we need
|
|
252
|
-
explore_data=client.explore_data,
|
|
253
|
-
build_project=partial(build_project, project=project, config=config),
|
|
254
|
-
deploy_project=partial(deploy_project, project=project, config=config),
|
|
255
|
-
deploy_check_project=partial(deploy_check_project, project=project, config=config),
|
|
256
|
-
mock_data=partial(mock_data, project=project, config=config),
|
|
257
|
-
append_data=partial(append_data, config=config),
|
|
258
|
-
analyze_fixture=partial(analyze_fixture, config=config),
|
|
259
|
-
execute_query_cloud=partial(execute_query_cloud, config=config),
|
|
260
|
-
execute_query_local=partial(execute_query_local, config=config),
|
|
261
|
-
request_endpoint_cloud=partial(request_endpoint_cloud, config=config),
|
|
262
|
-
request_endpoint_local=partial(request_endpoint_local, config=config),
|
|
263
|
-
get_datasource_datafile_cloud=partial(get_datasource_datafile_cloud, config=config),
|
|
264
|
-
get_datasource_datafile_local=partial(get_datasource_datafile_local, config=config),
|
|
265
|
-
get_pipe_datafile_cloud=partial(get_pipe_datafile_cloud, config=config),
|
|
266
|
-
get_pipe_datafile_local=partial(get_pipe_datafile_local, config=config),
|
|
267
|
-
get_connection_datafile_cloud=partial(get_connection_datafile_cloud, config=config),
|
|
268
|
-
get_connection_datafile_local=partial(get_connection_datafile_local, config=config),
|
|
269
|
-
get_project_files=project.get_project_files,
|
|
270
|
-
folder=folder,
|
|
271
|
-
thinking_animation=thinking_animation,
|
|
272
|
-
workspace_name=self.project.workspace_name,
|
|
273
|
-
dangerously_skip_permissions=self.dangerously_skip_permissions,
|
|
274
|
-
token=self.token,
|
|
275
|
-
user_token=self.user_token,
|
|
276
|
-
host=self.host,
|
|
277
|
-
),
|
|
168
|
+
deps=self._build_agent_deps(config),
|
|
278
169
|
message_history=self.messages,
|
|
279
170
|
)
|
|
280
171
|
new_messages = result.new_messages()
|
|
281
172
|
self.messages.extend(new_messages)
|
|
282
173
|
save_messages(new_messages)
|
|
283
|
-
thinking_animation.stop()
|
|
284
|
-
usage = result.usage()
|
|
285
|
-
request_tokens = usage.request_tokens or 0
|
|
286
|
-
response_tokens = usage.response_tokens or 0
|
|
287
|
-
total_tokens = usage.total_tokens or 0
|
|
288
|
-
cost = (
|
|
289
|
-
request_tokens * model_costs["input_cost_per_token"]
|
|
290
|
-
+ response_tokens * model_costs["output_cost_per_token"]
|
|
291
|
-
)
|
|
174
|
+
self.thinking_animation.stop()
|
|
292
175
|
click.echo(result.output)
|
|
293
|
-
|
|
294
|
-
|
|
176
|
+
self._echo_usage(config, result)
|
|
177
|
+
|
|
178
|
+
async def run_iter(self, user_prompt: str, config: dict[str, Any]) -> None:
|
|
179
|
+
user_prompt = f"{user_prompt}\n\n"
|
|
180
|
+
self.thinking_animation.start()
|
|
181
|
+
deps = self._build_agent_deps(config)
|
|
182
|
+
|
|
183
|
+
async with self.agent.iter(user_prompt, deps=deps, message_history=self.messages) as agent_run:
|
|
184
|
+
async for node in agent_run:
|
|
185
|
+
if hasattr(node, "model_response"):
|
|
186
|
+
for _i, part in enumerate(node.model_response.parts):
|
|
187
|
+
if hasattr(part, "content") and not agent_run.result:
|
|
188
|
+
animation_running = self.thinking_animation.running
|
|
189
|
+
if animation_running:
|
|
190
|
+
self.thinking_animation.stop()
|
|
191
|
+
click.echo(FeedbackManager.info(message=part.content))
|
|
192
|
+
if animation_running:
|
|
193
|
+
self.thinking_animation.start()
|
|
194
|
+
|
|
195
|
+
if agent_run.result is not None:
|
|
196
|
+
new_messages = agent_run.result.new_messages()
|
|
197
|
+
self.messages.extend(new_messages)
|
|
198
|
+
save_messages(new_messages)
|
|
199
|
+
self.thinking_animation.stop()
|
|
200
|
+
self._echo_usage(config, agent_run.result)
|
|
201
|
+
|
|
202
|
+
def _echo_usage(self, config: dict[str, Any], result: AgentRunResult) -> None:
|
|
295
203
|
if "@tinybird.co" in config.get("user_email", ""):
|
|
204
|
+
usage = result.usage()
|
|
205
|
+
request_tokens = usage.request_tokens or 0
|
|
206
|
+
response_tokens = usage.response_tokens or 0
|
|
207
|
+
total_tokens = usage.total_tokens or 0
|
|
208
|
+
cost = (
|
|
209
|
+
request_tokens * model_costs["input_cost_per_token"]
|
|
210
|
+
+ response_tokens * model_costs["output_cost_per_token"]
|
|
211
|
+
)
|
|
296
212
|
click.echo(f"Input tokens: {request_tokens}")
|
|
297
213
|
click.echo(f"Output tokens: {response_tokens}")
|
|
298
214
|
click.echo(f"Total tokens: {total_tokens}")
|
|
299
215
|
click.echo(f"Cost: ${cost:.6f}")
|
|
300
|
-
click.echo("\n")
|
|
301
216
|
|
|
302
217
|
|
|
303
218
|
def run_agent(
|
|
304
219
|
config: dict[str, Any], project: Project, dangerously_skip_permissions: bool, prompt: Optional[str] = None
|
|
305
220
|
):
|
|
221
|
+
click.echo(FeedbackManager.highlight(message="» Initializing Tinybird Code..."))
|
|
306
222
|
token = config.get("token", None)
|
|
307
223
|
host = config.get("host", None)
|
|
308
224
|
user_token = config.get("user_token", None)
|
|
@@ -319,9 +235,7 @@ def run_agent(
|
|
|
319
235
|
default=True,
|
|
320
236
|
)
|
|
321
237
|
if yes:
|
|
322
|
-
click.echo()
|
|
323
238
|
login(host, auth_host="https://cloud.tinybird.co", workspace=None, interactive=False, method="browser")
|
|
324
|
-
click.echo()
|
|
325
239
|
cli_config = CLIConfig.get_project_config()
|
|
326
240
|
config = {**config, **cli_config.to_dict()}
|
|
327
241
|
token = cli_config.get_token()
|
|
@@ -336,23 +250,22 @@ def run_agent(
|
|
|
336
250
|
)
|
|
337
251
|
return
|
|
338
252
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
253
|
+
build_project(config, project, test=False, silent=True)
|
|
254
|
+
|
|
255
|
+
# In prompt mode, always skip permissions to avoid interactive prompts
|
|
256
|
+
prompt_mode = prompt is not None
|
|
257
|
+
agent = TinybirdAgent(token, user_token, host, workspace_id, project, dangerously_skip_permissions, prompt_mode)
|
|
342
258
|
|
|
343
259
|
# Print mode: run once with the provided prompt and exit
|
|
344
260
|
if prompt:
|
|
345
|
-
agent.run(prompt, config
|
|
261
|
+
agent.run(prompt, config)
|
|
346
262
|
return
|
|
347
263
|
|
|
348
264
|
# Interactive mode: show banner and enter interactive loop
|
|
349
265
|
display_banner()
|
|
350
|
-
click.echo()
|
|
351
266
|
click.echo(FeedbackManager.info(message="Describe what you want to create and I'll help you build it"))
|
|
352
267
|
click.echo(FeedbackManager.info(message="Run /help for more commands"))
|
|
353
268
|
|
|
354
|
-
click.echo()
|
|
355
|
-
|
|
356
269
|
except Exception as e:
|
|
357
270
|
click.echo(FeedbackManager.error(message=f"Failed to initialize agent: {e}"))
|
|
358
271
|
return
|
|
@@ -365,32 +278,48 @@ def run_agent(
|
|
|
365
278
|
if user_input.startswith("tb "):
|
|
366
279
|
cmd_parts = shlex.split(user_input)
|
|
367
280
|
subprocess.run(cmd_parts)
|
|
368
|
-
click.echo()
|
|
369
281
|
continue
|
|
370
|
-
if user_input.lower() in ["/exit", "/quit"]:
|
|
282
|
+
if user_input.lower() in ["/exit", "/quit", "exit", "quit"]:
|
|
371
283
|
click.echo(FeedbackManager.info(message="Goodbye!"))
|
|
372
284
|
break
|
|
373
|
-
elif user_input.lower()
|
|
285
|
+
elif user_input.lower() in ["/clear", "clear"]:
|
|
374
286
|
clear_history()
|
|
287
|
+
click.echo(FeedbackManager.info(message="Message history cleared!"))
|
|
375
288
|
clear_messages()
|
|
376
289
|
continue
|
|
290
|
+
elif user_input.lower().startswith("select ") or user_input.lower().startswith("with "):
|
|
291
|
+
query = f"SELECT * FROM ({user_input.strip()}) FORMAT JSON"
|
|
292
|
+
result = execute_query_local(config, query=query)
|
|
293
|
+
stats = result["statistics"]
|
|
294
|
+
seconds = stats["elapsed"]
|
|
295
|
+
rows_read = humanfriendly.format_number(stats["rows_read"])
|
|
296
|
+
bytes_read = humanfriendly.format_size(stats["bytes_read"])
|
|
297
|
+
|
|
298
|
+
click.echo(FeedbackManager.info_query_stats(seconds=seconds, rows=rows_read, bytes=bytes_read))
|
|
299
|
+
|
|
300
|
+
if not result["data"]:
|
|
301
|
+
click.echo(FeedbackManager.info_no_rows())
|
|
302
|
+
else:
|
|
303
|
+
echo_safe_humanfriendly_tables_format_pretty_table(
|
|
304
|
+
data=[d.values() for d in result["data"][:10]], column_names=result["data"][0].keys()
|
|
305
|
+
)
|
|
306
|
+
click.echo("Showing first 10 results\n")
|
|
307
|
+
continue
|
|
377
308
|
elif user_input.lower() == "/login":
|
|
378
|
-
click.echo()
|
|
379
309
|
subprocess.run(["tb", "login"], check=True)
|
|
380
|
-
|
|
310
|
+
|
|
381
311
|
continue
|
|
382
312
|
elif user_input.lower() == "/help":
|
|
383
|
-
click.echo()
|
|
384
313
|
click.echo("• Describe what you want to create: 'Create a user analytics system'")
|
|
385
314
|
click.echo("• Ask for specific resources: 'Create a pipe to aggregate daily clicks'")
|
|
386
315
|
click.echo("• Connect to external services: 'Set up a Kafka connection for events'")
|
|
387
316
|
click.echo("• Type '/exit' or '/quit' to leave")
|
|
388
|
-
|
|
317
|
+
|
|
389
318
|
continue
|
|
390
319
|
elif user_input.strip() == "":
|
|
391
320
|
continue
|
|
392
321
|
else:
|
|
393
|
-
|
|
322
|
+
asyncio.run(agent.run_iter(user_input, config))
|
|
394
323
|
|
|
395
324
|
except KeyboardInterrupt:
|
|
396
325
|
click.echo(FeedbackManager.info(message="Goodbye!"))
|
|
@@ -436,11 +365,16 @@ def deploy_check_project(config: dict[str, Any], project: Project) -> None:
|
|
|
436
365
|
raise CLIDeploymentException(e.args[0])
|
|
437
366
|
|
|
438
367
|
|
|
439
|
-
def
|
|
368
|
+
def append_data_local(config: dict[str, Any], datasource_name: str, path: str) -> None:
|
|
440
369
|
client = get_tinybird_local_client(config, test=False, silent=False)
|
|
441
370
|
append_mock_data(client, datasource_name, path)
|
|
442
371
|
|
|
443
372
|
|
|
373
|
+
def append_data_cloud(config: dict[str, Any], datasource_name: str, path: str) -> None:
|
|
374
|
+
client = _get_tb_client(config["token"], config["host"])
|
|
375
|
+
append_mock_data(client, datasource_name, path)
|
|
376
|
+
|
|
377
|
+
|
|
444
378
|
def mock_data(
|
|
445
379
|
config: dict[str, Any],
|
|
446
380
|
project: Project,
|