PikoAi 0.1.17__py3-none-any.whl → 0.1.19__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.
@@ -9,7 +9,7 @@ from Utils.ter_interface import TerminalInterface
9
9
  from Utils.executor_utils import parse_tool_call
10
10
  from Agents.Executor.prompts import get_executor_prompt # Import prompts
11
11
 
12
- from llm_interface.llm import LiteLLMInterface # Import LiteLLMInterface
12
+ from llm_interface.llm import LiteLLMInterface # Import LiteLLMInterfacea
13
13
  from Tools import tool_manager
14
14
 
15
15
  class RateLimiter:
@@ -29,7 +29,7 @@ class executor:
29
29
  def __init__(self, user_prompt, max_iter=10):
30
30
  self.user_prompt = user_prompt
31
31
  self.max_iter = max_iter
32
- self.rate_limiter = RateLimiter(wait_time=5.0, max_retries=3)
32
+ self.rate_limiter = RateLimiter(wait_time=3.0, max_retries=3)
33
33
  self.executor_prompt_init() # Update system_prompt
34
34
  # self.python_executor = python_executor.PythonExecutor() # Initialize PythonExecutor
35
35
  # self.shell_executor = ShellExecutor() # Initialize ShellExecutor
@@ -80,7 +80,7 @@ class executor:
80
80
 
81
81
  except Exception as e: # Catching generic Exception as LiteLLM maps to OpenAI exceptions
82
82
  # Check if the error message contains "429" for rate limiting
83
- if "429" in str(e) and retries < self.rate_limiter.max_retries:
83
+ if retries < self.rate_limiter.max_retries:
84
84
  retries += 1
85
85
  print(f"\nRate limit error detected. Waiting {self.rate_limiter.wait_time} seconds before retry {retries}/{self.rate_limiter.max_retries}")
86
86
  time.sleep(self.rate_limiter.wait_time)
Utils/ter_interface.py CHANGED
@@ -68,7 +68,8 @@ class TerminalInterface:
68
68
 
69
69
  # Handle tool call closing delimiter - be more flexible with whitespace
70
70
  elif "<<END_TOOL_CALL>>" in line_stripped:
71
- self.console.print(Syntax('{"status": "end_tool_call"}', "json", theme="monokai", line_numbers=False))
71
+ self.console.print(self.tool_call_buffer)
72
+ # self.console.print(Syntax('{"status": "end_tool_call"}', "json", theme="monokai", line_numbers=False))
72
73
  self.console.print("[bold cyan]--------------------------------[/bold cyan]")
73
74
  self.inside_tool_call = False
74
75
  self.tool_call_buffer = ""
cli.py CHANGED
@@ -32,6 +32,10 @@ AVAILABLE_MODELS = {
32
32
  "anthropic/claude-3-opus-20240229",
33
33
  "anthropic/claude-3-sonnet-20240229",
34
34
  "anthropic/claude-3-haiku-20240307"
35
+ ],
36
+ "gemini": [
37
+ "gemini/gemini-2.0-flash",
38
+ "gemini/gemini-2.5-flash-preview-05-20"
35
39
  ]
36
40
  }
37
41
 
@@ -40,7 +44,8 @@ API_KEYS = {
40
44
  "openai": "OPENAI_API_KEY",
41
45
  "mistral": "MISTRAL_API_KEY",
42
46
  "groq": "GROQ_API_KEY",
43
- "anthropic": "ANTHROPIC_API_KEY"
47
+ "anthropic": "ANTHROPIC_API_KEY",
48
+ "gemini": "GEMINI_API_KEY"
44
49
  }
45
50
 
46
51
  # --- Utility Functions ---
@@ -72,7 +77,6 @@ def load_config(config_path: str) -> dict:
72
77
  with open(config_path, 'r') as f:
73
78
  try:
74
79
  config = json.load(f)
75
- config["working_directory"] = os.getcwd()
76
80
  except json.JSONDecodeError:
77
81
  print("Error reading config.json. File might be corrupted. Re-creating default.")
78
82
  config = { "working_directory": os.getcwd(), "llm_provider": None, "model_name": None }
@@ -148,13 +152,20 @@ def update_model_config(config_path: str, provider_key: str, model_name_full: st
148
152
 
149
153
  # --- CLI Commands ---
150
154
 
151
- @click.group(invoke_without_command=True)
152
- @click.option("--task", "-t", help="The task to automate")
153
- @click.option("--max-iter", "-m", default=10, help="Maximum number of iterations for the task")
154
- @click.option("--change-model", is_flag=True, help="Change the LLM provider and model")
155
+ @click.group(invoke_without_command=True, help="TaskAutomator – Your AI Task Automation Tool\n\nThis tool helps automate tasks using AI. You can run tasks directly or use various commands to manage settings and tools.")
156
+ @click.option("--task", "-t", help="The task to automate (e.g., 'create a python script that sorts files by date')")
157
+ @click.option("--max-iter", "-m", default=10, help="Maximum number of iterations for the task (default: 10)")
158
+ @click.option("--change-model", is_flag=True, help="Change the LLM provider and model before running the task")
155
159
  @click.pass_context
156
160
  def cli(ctx, task, max_iter, change_model):
157
- """TaskAutomator – Your AI Task Automation Tool"""
161
+ """TaskAutomator – Your AI Task Automation Tool
162
+
163
+ This tool helps automate tasks using AI. You can:
164
+ - Run tasks directly with --task
165
+ - Change AI models with --change-model
166
+ - Manage API keys with set-api-key and set-serp-key
167
+ - List available tools and models
168
+ """
158
169
  config_path = os.path.join(os.path.dirname(__file__), '../config.json')
159
170
  config = load_config(config_path)
160
171
  save_config(config_path, config)
@@ -185,9 +196,13 @@ def cli(ctx, task, max_iter, change_model):
185
196
  else:
186
197
  copilot.run()
187
198
 
188
- @cli.command("list-tools")
199
+ @cli.command("list-tools", help="List all available automation tools and their descriptions")
189
200
  def list_tools():
190
- """List all available automation tools."""
201
+ """List all available automation tools and their descriptions.
202
+
203
+ This command shows all tools that can be used by the AI to automate tasks,
204
+ including what each tool does and what arguments it accepts.
205
+ """
191
206
  tools = OpenCopilot.list_available_tools()
192
207
  click.echo("Available Tools:")
193
208
  for tool in tools:
@@ -195,20 +210,32 @@ def list_tools():
195
210
  if tool.get("arguments"):
196
211
  click.echo(f" Arguments: {tool['arguments']}")
197
212
 
198
- @cli.command("list-models")
213
+ @cli.command("list-models", help="List all available LLM providers and their models")
199
214
  def list_models():
200
- """List all available LLM providers and their models (litellm compatible)."""
215
+ """List all available LLM providers and their models.
216
+
217
+ Shows all supported AI models that can be used for task automation,
218
+ organized by provider (OpenAI, Mistral, Groq, Anthropic).
219
+ """
201
220
  click.echo("Available LLM Providers and Models (litellm compatible):")
202
221
  for (provider_key, model_list) in AVAILABLE_MODELS.items():
203
222
  click.echo(f"\n{provider_key.upper()}:")
204
223
  for model_name_full in model_list:
205
224
  click.echo(f" - {model_name_full}")
206
225
 
207
- @cli.command("set-api-key")
208
- @click.option("--provider", "-p", type=click.Choice(list(AVAILABLE_MODELS.keys())), help="The LLM provider to set API key for")
209
- @click.option("--key", "-k", help="The API key to set (if not provided, will prompt for it)")
226
+ @cli.command("set-api-key", help="Set or update API key for an LLM provider")
227
+ @click.option("--provider", "-p", type=click.Choice(list(AVAILABLE_MODELS.keys())), help="The LLM provider to set API key for (e.g., openai, mistral, groq, anthropic)")
228
+ @click.option("--key", "-k", help="The API key to set (if not provided, will prompt for it securely)")
210
229
  def set_api_key(provider, key):
211
- """Set or update API key for a specific LLM provider."""
230
+ """Set or update API key for an LLM provider.
231
+
232
+ This command allows you to set or update the API key for any supported LLM provider.
233
+ The key will be stored securely in your .env file.
234
+
235
+ Examples:
236
+ piko set-api-key --provider openai
237
+ piko set-api-key -p mistral -k your-key-here
238
+ """
212
239
  if not provider:
213
240
  questions = [ inquirer.List("provider_key", message="Select LLM Provider to update API key", choices=list(AVAILABLE_MODELS.keys())) ]
214
241
  provider = inquirer.prompt(questions)["provider_key"]
@@ -236,10 +263,18 @@ def set_api_key(provider, key):
236
263
  f.writelines(lines)
237
264
  click.echo(f"API key for {provider.upper()} has been updated successfully in {env_path}")
238
265
 
239
- @cli.command("set-serp-key")
240
- @click.option("--key", "-k", help="The SERP API key to set (if not provided, will prompt for it)")
266
+ @cli.command("set-serp-key", help="Set or update the SERP API key for web search functionality")
267
+ @click.option("--key", "-k", help="The SERP API key to set (if not provided, will prompt for it securely)")
241
268
  def set_serp_key(key):
242
- """Set or update the SERP API key used for web search functionality."""
269
+ """Set or update the SERP API key used for web search functionality.
270
+
271
+ This command sets the API key used for web search operations when DuckDuckGo
272
+ search is not available. The key will be stored securely in your .env file.
273
+
274
+ Examples:
275
+ piko set-serp-key
276
+ piko set-serp-key -k your-key-here
277
+ """
243
278
  if not key:
244
279
  questions = [ inquirer.Text("api_key", message="Enter your SERP API key", validate=lambda _, x: len(x.strip()) > 0) ]
245
280
  key = inquirer.prompt(questions)["api_key"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PikoAi
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  Summary: An AI-powered task automation tool
5
5
  Home-page: https://github.com/nihaaaar22/OS-Assistant
6
6
  Author: Nihar S
@@ -1,8 +1,8 @@
1
1
  OpenCopilot.py,sha256=kPTs0-ly84h4dM7AmBlK4uwst5Sj2AM6UAlE3okkD8U,12157
2
- cli.py,sha256=MJSassshPDTHrvdw3kRDob7CK1CeEir_TgJvMv4cxyw,11229
2
+ cli.py,sha256=2UvmH74pcBFFezI0WHNyWTHMYasIM5NGnrUX6wsdveM,12945
3
3
  Agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  Agents/Executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- Agents/Executor/executor.py,sha256=kk5TpfTUrunIl1gv5ZZO2UIm5PC4ZygeiB4z0YAJ_PY,7018
5
+ Agents/Executor/executor.py,sha256=BzSYkT4aPW1yDLSNXNr9WEWZEcs1becEYYlop-eB8s8,6999
6
6
  Agents/Executor/prompts.py,sha256=pGY4uXNGYiw_TnTUsRjrVsWc9CV657q3916eui0oulU,2688
7
7
  Env/__init__.py,sha256=KLe7UcNV5L395SxhMwbYGyu7KPrSNaoV_9QJo3mLop0,196
8
8
  Env/base_env.py,sha256=K4PoWwPXn3pKeu7_-JOlUuyNbyYQ9itMhQybFOm-3K4,1563
@@ -24,12 +24,12 @@ Tools/web_loader.py,sha256=_oP48uwveTaCKU7G5ju2zsJGTcZd1ScXTKOvHDFtZJU,4564
24
24
  Tools/web_search.py,sha256=12_VhwJGXmn3oUNhTbQ5ENFG964t9DWkfCz3UtlxrbM,2261
25
25
  Utils/__init__.py,sha256=oukU0ufroPRd8_N8d2xiFes9CTxSaw4NA6p2nS1kkSg,16
26
26
  Utils/executor_utils.py,sha256=WwK3TKgw_hG_crg7ijRaqfidYnnNXYbbs37vKZRYK-0,491
27
- Utils/ter_interface.py,sha256=2k32kVxcxVBewXnjSGSPbx25ZLhKindEMtL6wSC_wL4,3829
27
+ Utils/ter_interface.py,sha256=8Oe5818MAYC21SfUxtfnV9HQFcQ49z8Q030jjPqNP_g,3889
28
28
  llm_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  llm_interface/llm.py,sha256=tI_KDOW14QLWowA7bB3GPe2qjlk0sjS5fBavs9XD1fo,5185
30
- pikoai-0.1.17.dist-info/licenses/LICENSE,sha256=cELUVOboOAderKFp8bdtcM5VyJi61YH1oDbRhOuoQZw,1067
31
- pikoai-0.1.17.dist-info/METADATA,sha256=6RNL3fe8b177XNA4YfqQKC9o8YFe--RQ5DKBafQfhpg,2962
32
- pikoai-0.1.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
- pikoai-0.1.17.dist-info/entry_points.txt,sha256=xjZnheDymNDnQ0o84R0jZKEITrhNbzQWN-AhqfA_d6s,50
34
- pikoai-0.1.17.dist-info/top_level.txt,sha256=hWzBNE7UQsuNcENIOksGcJED08k3ZGRRn2X5jnStICU,53
35
- pikoai-0.1.17.dist-info/RECORD,,
30
+ pikoai-0.1.19.dist-info/licenses/LICENSE,sha256=cELUVOboOAderKFp8bdtcM5VyJi61YH1oDbRhOuoQZw,1067
31
+ pikoai-0.1.19.dist-info/METADATA,sha256=4N9c6Htp6lsrimD8ukdfxTZG59quiJodw6pIECoLVPg,2962
32
+ pikoai-0.1.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
+ pikoai-0.1.19.dist-info/entry_points.txt,sha256=xjZnheDymNDnQ0o84R0jZKEITrhNbzQWN-AhqfA_d6s,50
34
+ pikoai-0.1.19.dist-info/top_level.txt,sha256=hWzBNE7UQsuNcENIOksGcJED08k3ZGRRn2X5jnStICU,53
35
+ pikoai-0.1.19.dist-info/RECORD,,