asktable-advisor 1.0.1__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.
- asktable_advisor/__init__.py +18 -0
- asktable_advisor/__main__.py +156 -0
- asktable_advisor/__version__.py +4 -0
- asktable_advisor/agent/__init__.py +6 -0
- asktable_advisor/agent/advisor.py +337 -0
- asktable_advisor/agent/llm_client.py +195 -0
- asktable_advisor/agent/prompts.py +135 -0
- asktable_advisor/agent/tools.py +324 -0
- asktable_advisor/asktable/__init__.py +0 -0
- asktable_advisor/asktable/client.py +271 -0
- asktable_advisor/asktable/inspector.py +210 -0
- asktable_advisor/asktable/resources/__init__.py +0 -0
- asktable_advisor/config.py +79 -0
- asktable_advisor/conversation/__init__.py +0 -0
- asktable_advisor/database/__init__.py +0 -0
- asktable_advisor/database/data_generator.py +143 -0
- asktable_advisor/database/manager.py +228 -0
- asktable_advisor/database/schema_generator.py +148 -0
- asktable_advisor/knowledge/__init__.py +0 -0
- asktable_advisor/utils/__init__.py +0 -0
- asktable_advisor-1.0.1.dist-info/METADATA +265 -0
- asktable_advisor-1.0.1.dist-info/RECORD +26 -0
- asktable_advisor-1.0.1.dist-info/WHEEL +5 -0
- asktable_advisor-1.0.1.dist-info/entry_points.txt +2 -0
- asktable_advisor-1.0.1.dist-info/licenses/LICENSE +201 -0
- asktable_advisor-1.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AskTable Advisor - AI Agent for AskTable scenario building.
|
|
3
|
+
|
|
4
|
+
A conversational AI agent that helps users quickly create and manage
|
|
5
|
+
high-quality AskTable demo projects.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .__version__ import __version__, __version_info__
|
|
9
|
+
from .config import AdvisorSettings, get_settings
|
|
10
|
+
from .agent.advisor import AdvisorAgent
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"__version__",
|
|
14
|
+
"__version_info__",
|
|
15
|
+
"AdvisorSettings",
|
|
16
|
+
"get_settings",
|
|
17
|
+
"AdvisorAgent",
|
|
18
|
+
]
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""Command-line interface for AskTable Advisor."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.panel import Panel
|
|
9
|
+
from rich.markdown import Markdown
|
|
10
|
+
from rich.prompt import Prompt
|
|
11
|
+
|
|
12
|
+
from .config import AdvisorSettings, get_settings
|
|
13
|
+
from .agent.advisor import AdvisorAgent
|
|
14
|
+
|
|
15
|
+
# Setup console
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
# Setup logging
|
|
19
|
+
logging.basicConfig(
|
|
20
|
+
level=logging.INFO,
|
|
21
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
22
|
+
handlers=[
|
|
23
|
+
logging.FileHandler("asktable_advisor.log"),
|
|
24
|
+
logging.StreamHandler(sys.stderr),
|
|
25
|
+
],
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def print_welcome() -> None:
|
|
30
|
+
"""Print welcome message."""
|
|
31
|
+
welcome_text = """
|
|
32
|
+
# 🤖 AskTable Advisor v1.0
|
|
33
|
+
|
|
34
|
+
你好!我是 AskTable Advisor,你的 AskTable 场景构建助手。
|
|
35
|
+
|
|
36
|
+
## 我能帮你:
|
|
37
|
+
- 🎨 **创建新场景**:告诉我场景名称(如"电商平台"、"在线教育"),我会自动设计并构建完整的演示项目
|
|
38
|
+
- 📊 **查看现有场景**:检查你的 AskTable 项目中已有的资源
|
|
39
|
+
- ✨ **完善场景**:优化现有场景,添加更多功能
|
|
40
|
+
|
|
41
|
+
## 使用方式:
|
|
42
|
+
直接用自然语言告诉我你想做什么!例如:
|
|
43
|
+
- "创建一个在线教育平台的演示场景"
|
|
44
|
+
- "看看我现在有哪些场景"
|
|
45
|
+
- "给电商 Bot 添加更多示例问题"
|
|
46
|
+
|
|
47
|
+
输入 **exit** 或 **quit** 退出。
|
|
48
|
+
|
|
49
|
+
开始对话吧!
|
|
50
|
+
"""
|
|
51
|
+
console.print(Panel(Markdown(welcome_text), border_style="cyan"))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def run_chat_loop(agent: AdvisorAgent) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Run the main chat loop.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
agent: Advisor agent instance
|
|
60
|
+
"""
|
|
61
|
+
while True:
|
|
62
|
+
try:
|
|
63
|
+
# Get user input
|
|
64
|
+
user_input = Prompt.ask("\n[bold cyan]你[/bold cyan]").strip()
|
|
65
|
+
|
|
66
|
+
# Check for exit commands
|
|
67
|
+
if user_input.lower() in ["exit", "quit", "退出", "再见"]:
|
|
68
|
+
console.print("\n[dim]再见!如有需要随时回来 👋[/dim]\n")
|
|
69
|
+
break
|
|
70
|
+
|
|
71
|
+
# Skip empty input
|
|
72
|
+
if not user_input:
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
# Process with agent
|
|
76
|
+
console.print("\n[bold green]Advisor[/bold green]: ", end="")
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
response = agent.chat(user_input)
|
|
80
|
+
console.print(response)
|
|
81
|
+
|
|
82
|
+
except Exception as e:
|
|
83
|
+
console.print(f"\n[red]错误:{str(e)}[/red]")
|
|
84
|
+
logging.error(f"Error processing message: {e}", exc_info=True)
|
|
85
|
+
|
|
86
|
+
except KeyboardInterrupt:
|
|
87
|
+
console.print("\n\n[dim]检测到 Ctrl+C,退出程序...[/dim]\n")
|
|
88
|
+
break
|
|
89
|
+
|
|
90
|
+
except EOFError:
|
|
91
|
+
console.print("\n\n[dim]输入结束,退出程序...[/dim]\n")
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_connections(agent: AdvisorAgent) -> bool:
|
|
96
|
+
"""
|
|
97
|
+
Test all connections.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
agent: Advisor agent instance
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
True if all connections successful
|
|
104
|
+
"""
|
|
105
|
+
console.print("\n[cyan]正在测试连接...[/cyan]\n")
|
|
106
|
+
|
|
107
|
+
results = agent.test_connections()
|
|
108
|
+
|
|
109
|
+
all_ok = True
|
|
110
|
+
for service, ok in results.items():
|
|
111
|
+
status = "[green]✓[/green]" if ok else "[red]✗[/red]"
|
|
112
|
+
console.print(f"{status} {service.upper()} 连接")
|
|
113
|
+
all_ok = all_ok and ok
|
|
114
|
+
|
|
115
|
+
console.print()
|
|
116
|
+
|
|
117
|
+
if not all_ok:
|
|
118
|
+
console.print(
|
|
119
|
+
"[yellow]警告:部分服务连接失败,某些功能可能无法使用[/yellow]\n"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return all_ok
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def main() -> None:
|
|
126
|
+
"""Main entry point for CLI."""
|
|
127
|
+
try:
|
|
128
|
+
# Load settings
|
|
129
|
+
settings = get_settings()
|
|
130
|
+
|
|
131
|
+
# Print welcome
|
|
132
|
+
print_welcome()
|
|
133
|
+
|
|
134
|
+
# Initialize agent
|
|
135
|
+
console.print("[dim]正在初始化 Advisor Agent...[/dim]")
|
|
136
|
+
agent = AdvisorAgent(settings)
|
|
137
|
+
|
|
138
|
+
# Test connections
|
|
139
|
+
test_connections(agent)
|
|
140
|
+
|
|
141
|
+
# Start chat loop
|
|
142
|
+
console.print("[dim]准备就绪!开始对话:[/dim]\n")
|
|
143
|
+
run_chat_loop(agent)
|
|
144
|
+
|
|
145
|
+
except KeyboardInterrupt:
|
|
146
|
+
console.print("\n\n[dim]程序被中断[/dim]\n")
|
|
147
|
+
sys.exit(0)
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
console.print(f"\n[red bold]错误:{str(e)}[/red bold]\n")
|
|
151
|
+
logging.error(f"Fatal error: {e}", exc_info=True)
|
|
152
|
+
sys.exit(1)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
if __name__ == "__main__":
|
|
156
|
+
main()
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"""Main Advisor Agent with conversational AI and tool execution."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
from anthropic.types import Message, MessageParam
|
|
8
|
+
|
|
9
|
+
from ..config import AdvisorSettings
|
|
10
|
+
from ..asktable.client import AskTableClient
|
|
11
|
+
from ..asktable.inspector import AskTableInspector
|
|
12
|
+
from ..database.manager import DatabaseManager
|
|
13
|
+
from ..database.schema_generator import SchemaGenerator
|
|
14
|
+
from ..database.data_generator import DataGenerator
|
|
15
|
+
from .llm_client import LLMClient
|
|
16
|
+
from .tools import get_tools
|
|
17
|
+
from .prompts import get_system_prompt
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AdvisorAgent:
|
|
23
|
+
"""
|
|
24
|
+
AskTable Advisor AI Agent.
|
|
25
|
+
|
|
26
|
+
Conversational agent that helps users create and manage AskTable scenarios.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, settings: AdvisorSettings):
|
|
30
|
+
"""
|
|
31
|
+
Initialize Advisor Agent.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
settings: Application settings
|
|
35
|
+
"""
|
|
36
|
+
self.settings = settings
|
|
37
|
+
|
|
38
|
+
# Initialize components
|
|
39
|
+
self.llm_client = LLMClient(settings)
|
|
40
|
+
self.db_manager = DatabaseManager(settings)
|
|
41
|
+
self.asktable_client = AskTableClient(
|
|
42
|
+
api_key=settings.asktable_api_key,
|
|
43
|
+
base_url=settings.asktable_api_base,
|
|
44
|
+
)
|
|
45
|
+
self.asktable_inspector = AskTableInspector(self.asktable_client)
|
|
46
|
+
|
|
47
|
+
# Generators
|
|
48
|
+
self.schema_generator = SchemaGenerator(self.llm_client)
|
|
49
|
+
self.data_generator = DataGenerator(self.llm_client)
|
|
50
|
+
|
|
51
|
+
# Conversation state
|
|
52
|
+
self.conversation_history: List[MessageParam] = []
|
|
53
|
+
self.system_prompt = get_system_prompt()
|
|
54
|
+
self.tools = get_tools()
|
|
55
|
+
|
|
56
|
+
logger.info("Advisor Agent initialized")
|
|
57
|
+
|
|
58
|
+
def chat(self, user_message: str) -> str:
|
|
59
|
+
"""
|
|
60
|
+
Process user message and return response.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
user_message: User's input message
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Agent's response text
|
|
67
|
+
"""
|
|
68
|
+
# Add user message to history
|
|
69
|
+
self.conversation_history.append({
|
|
70
|
+
"role": "user",
|
|
71
|
+
"content": user_message,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
# Process with LLM and tools
|
|
75
|
+
response_text = self._process_turn()
|
|
76
|
+
|
|
77
|
+
return response_text
|
|
78
|
+
|
|
79
|
+
def _process_turn(self) -> str:
|
|
80
|
+
"""Process one conversation turn with potential tool use."""
|
|
81
|
+
max_iterations = 10 # Prevent infinite loops
|
|
82
|
+
iteration = 0
|
|
83
|
+
|
|
84
|
+
while iteration < max_iterations:
|
|
85
|
+
iteration += 1
|
|
86
|
+
|
|
87
|
+
# Call LLM
|
|
88
|
+
response = self.llm_client.create_message(
|
|
89
|
+
messages=self.conversation_history,
|
|
90
|
+
system=self.system_prompt,
|
|
91
|
+
tools=self.tools,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Check if LLM wants to use tools
|
|
95
|
+
if self.llm_client.has_tool_use(response):
|
|
96
|
+
# Execute tools and continue
|
|
97
|
+
self._execute_tools(response)
|
|
98
|
+
else:
|
|
99
|
+
# LLM has final response
|
|
100
|
+
response_text = self.llm_client.extract_text(response)
|
|
101
|
+
|
|
102
|
+
# Add assistant response to history
|
|
103
|
+
self.conversation_history.append({
|
|
104
|
+
"role": "assistant",
|
|
105
|
+
"content": response_text,
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
return response_text
|
|
109
|
+
|
|
110
|
+
# Max iterations reached
|
|
111
|
+
error_msg = "对话迭代次数过多,请重新开始"
|
|
112
|
+
logger.warning(f"Max iterations reached in conversation")
|
|
113
|
+
return error_msg
|
|
114
|
+
|
|
115
|
+
def _execute_tools(self, message: Message) -> None:
|
|
116
|
+
"""
|
|
117
|
+
Execute tools requested by LLM.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
message: LLM message containing tool use blocks
|
|
121
|
+
"""
|
|
122
|
+
# Add assistant message with tool use to history
|
|
123
|
+
self.conversation_history.append({
|
|
124
|
+
"role": "assistant",
|
|
125
|
+
"content": message.content,
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
# Extract and execute each tool
|
|
129
|
+
tool_uses = self.llm_client.extract_tool_uses(message)
|
|
130
|
+
|
|
131
|
+
for tool_use in tool_uses:
|
|
132
|
+
tool_name = tool_use.name
|
|
133
|
+
tool_input = tool_use.input
|
|
134
|
+
tool_use_id = tool_use.id
|
|
135
|
+
|
|
136
|
+
logger.info(f"Executing tool: {tool_name}")
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
# Execute tool
|
|
140
|
+
result = self._execute_tool(tool_name, tool_input)
|
|
141
|
+
|
|
142
|
+
# Format result
|
|
143
|
+
tool_result = self.llm_client.format_tool_result(
|
|
144
|
+
tool_use_id=tool_use_id,
|
|
145
|
+
content=result,
|
|
146
|
+
is_error=False,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
logger.error(f"Tool execution failed: {e}")
|
|
151
|
+
tool_result = self.llm_client.format_tool_result(
|
|
152
|
+
tool_use_id=tool_use_id,
|
|
153
|
+
content=f"工具执行失败:{str(e)}",
|
|
154
|
+
is_error=True,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Add tool result to history
|
|
158
|
+
self.conversation_history.append({
|
|
159
|
+
"role": "user",
|
|
160
|
+
"content": [tool_result],
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
def _execute_tool(self, tool_name: str, tool_input: Dict[str, Any]) -> Any:
|
|
164
|
+
"""
|
|
165
|
+
Execute a specific tool.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
tool_name: Name of the tool to execute
|
|
169
|
+
tool_input: Tool input parameters
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Tool execution result
|
|
173
|
+
"""
|
|
174
|
+
# Dispatch to appropriate handler
|
|
175
|
+
if tool_name == "inspect_asktable_project":
|
|
176
|
+
return self._tool_inspect_project(tool_input)
|
|
177
|
+
|
|
178
|
+
elif tool_name == "design_database_schema":
|
|
179
|
+
return self._tool_design_schema(tool_input)
|
|
180
|
+
|
|
181
|
+
elif tool_name == "generate_sample_data":
|
|
182
|
+
return self._tool_generate_data(tool_input)
|
|
183
|
+
|
|
184
|
+
elif tool_name == "execute_sql":
|
|
185
|
+
return self._tool_execute_sql(tool_input)
|
|
186
|
+
|
|
187
|
+
elif tool_name == "create_asktable_datasource":
|
|
188
|
+
return self._tool_create_datasource(tool_input)
|
|
189
|
+
|
|
190
|
+
elif tool_name == "create_asktable_bot":
|
|
191
|
+
return self._tool_create_bot(tool_input)
|
|
192
|
+
|
|
193
|
+
elif tool_name == "create_asktable_chat":
|
|
194
|
+
return self._tool_create_chat(tool_input)
|
|
195
|
+
|
|
196
|
+
elif tool_name == "enhance_bot":
|
|
197
|
+
return self._tool_enhance_bot(tool_input)
|
|
198
|
+
|
|
199
|
+
elif tool_name == "create_permissions":
|
|
200
|
+
return self._tool_create_permissions(tool_input)
|
|
201
|
+
|
|
202
|
+
elif tool_name == "ask_user":
|
|
203
|
+
return self._tool_ask_user(tool_input)
|
|
204
|
+
|
|
205
|
+
else:
|
|
206
|
+
raise ValueError(f"Unknown tool: {tool_name}")
|
|
207
|
+
|
|
208
|
+
# Tool implementations
|
|
209
|
+
def _tool_inspect_project(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
210
|
+
"""Inspect AskTable project."""
|
|
211
|
+
detailed = params.get("detailed", False)
|
|
212
|
+
return self.asktable_inspector.inspect_project(detailed=detailed)
|
|
213
|
+
|
|
214
|
+
def _tool_design_schema(self, params: Dict[str, Any]) -> str:
|
|
215
|
+
"""Design database schema."""
|
|
216
|
+
return self.schema_generator.generate_schema(
|
|
217
|
+
scenario_name=params["scenario_name"],
|
|
218
|
+
scenario_description=params["scenario_description"],
|
|
219
|
+
requirements=params.get("requirements"),
|
|
220
|
+
scale_info=params.get("scale_info"),
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
def _tool_generate_data(self, params: Dict[str, Any]) -> str:
|
|
224
|
+
"""Generate sample data."""
|
|
225
|
+
return self.data_generator.generate_data(
|
|
226
|
+
schema_sql=params["schema_sql"],
|
|
227
|
+
scenario_context=params.get("scenario_context", ""),
|
|
228
|
+
data_volume=params["data_volume"],
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
def _tool_execute_sql(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
232
|
+
"""Execute SQL statements."""
|
|
233
|
+
sql = params["sql"]
|
|
234
|
+
description = params.get("description", "执行 SQL")
|
|
235
|
+
|
|
236
|
+
count = self.db_manager.execute_sql(sql, description)
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
"success": True,
|
|
240
|
+
"statements_executed": count,
|
|
241
|
+
"message": f"成功执行 {count} 条 SQL 语句",
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
def _tool_create_datasource(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
245
|
+
"""Create AskTable datasource."""
|
|
246
|
+
datasource = self.asktable_client.create_datasource(
|
|
247
|
+
name=params["name"],
|
|
248
|
+
database_name=params["database_name"],
|
|
249
|
+
description=params.get("description"),
|
|
250
|
+
)
|
|
251
|
+
return datasource
|
|
252
|
+
|
|
253
|
+
def _tool_create_bot(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
254
|
+
"""Create AskTable bot."""
|
|
255
|
+
bot = self.asktable_client.create_bot(
|
|
256
|
+
name=params["name"],
|
|
257
|
+
datasource_id=params["datasource_id"],
|
|
258
|
+
description=params.get("description"),
|
|
259
|
+
instructions=params.get("instructions"),
|
|
260
|
+
sample_questions=params.get("sample_questions"),
|
|
261
|
+
)
|
|
262
|
+
return bot
|
|
263
|
+
|
|
264
|
+
def _tool_create_chat(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
265
|
+
"""Create AskTable chat."""
|
|
266
|
+
chat = self.asktable_client.create_chat(
|
|
267
|
+
bot_id=params["bot_id"],
|
|
268
|
+
name=params["name"],
|
|
269
|
+
)
|
|
270
|
+
return chat
|
|
271
|
+
|
|
272
|
+
def _tool_enhance_bot(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
273
|
+
"""Enhance existing bot."""
|
|
274
|
+
bot_id = params["bot_id"]
|
|
275
|
+
action = params["action"]
|
|
276
|
+
content = params.get("content", {})
|
|
277
|
+
|
|
278
|
+
if action == "add_questions":
|
|
279
|
+
# Get current bot
|
|
280
|
+
bot = self.asktable_client.get_bot(bot_id)
|
|
281
|
+
if not bot:
|
|
282
|
+
raise ValueError(f"Bot not found: {bot_id}")
|
|
283
|
+
|
|
284
|
+
# Add new questions
|
|
285
|
+
current_questions = bot.get("sample_questions", [])
|
|
286
|
+
new_questions = content.get("questions", [])
|
|
287
|
+
all_questions = current_questions + new_questions
|
|
288
|
+
|
|
289
|
+
# Update bot
|
|
290
|
+
updated_bot = self.asktable_client.update_bot(
|
|
291
|
+
bot_id=bot_id,
|
|
292
|
+
sample_questions=all_questions,
|
|
293
|
+
)
|
|
294
|
+
return updated_bot
|
|
295
|
+
|
|
296
|
+
elif action == "update_instructions":
|
|
297
|
+
updated_bot = self.asktable_client.update_bot(
|
|
298
|
+
bot_id=bot_id,
|
|
299
|
+
instructions=content.get("instructions"),
|
|
300
|
+
)
|
|
301
|
+
return updated_bot
|
|
302
|
+
|
|
303
|
+
else:
|
|
304
|
+
raise ValueError(f"Unknown action: {action}")
|
|
305
|
+
|
|
306
|
+
def _tool_create_permissions(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
307
|
+
"""Create permissions (placeholder)."""
|
|
308
|
+
# This is a placeholder for future implementation
|
|
309
|
+
return {
|
|
310
|
+
"message": "权限配置功能尚未实现,这是占位符",
|
|
311
|
+
"datasource_id": params.get("datasource_id"),
|
|
312
|
+
"roles": params.get("roles", []),
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
def _tool_ask_user(self, params: Dict[str, Any]) -> str:
|
|
316
|
+
"""Ask user a question (returns question to be displayed)."""
|
|
317
|
+
# In CLI mode, this will be handled by the CLI layer
|
|
318
|
+
# For now, just return the question
|
|
319
|
+
question = params["question"]
|
|
320
|
+
options = params.get("options")
|
|
321
|
+
|
|
322
|
+
if options:
|
|
323
|
+
return f"{question}\n选项:{', '.join(options)}"
|
|
324
|
+
return question
|
|
325
|
+
|
|
326
|
+
def reset_conversation(self) -> None:
|
|
327
|
+
"""Reset conversation history."""
|
|
328
|
+
self.conversation_history = []
|
|
329
|
+
logger.info("Conversation reset")
|
|
330
|
+
|
|
331
|
+
def test_connections(self) -> Dict[str, bool]:
|
|
332
|
+
"""Test all connections."""
|
|
333
|
+
return {
|
|
334
|
+
"llm": self.llm_client.test_connection(),
|
|
335
|
+
"database": self.db_manager.test_connection(),
|
|
336
|
+
"asktable": self.asktable_client.test_connection(),
|
|
337
|
+
}
|