supyagent 0.2.1__tar.gz → 0.2.2__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 supyagent might be problematic. Click here for more details.

Files changed (48) hide show
  1. {supyagent-0.2.1 → supyagent-0.2.2}/.gitignore +1 -0
  2. {supyagent-0.2.1 → supyagent-0.2.2}/PKG-INFO +1 -1
  3. supyagent-0.2.2/agents/tester.yaml +23 -0
  4. {supyagent-0.2.1 → supyagent-0.2.2}/pyproject.toml +1 -1
  5. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/cli/main.py +12 -15
  6. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/llm.py +4 -0
  7. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/tools.py +43 -25
  8. supyagent-0.2.2/supypowers/__init__.py +1 -0
  9. supyagent-0.2.1/supypowers/__init__.py +0 -6
  10. {supyagent-0.2.1 → supyagent-0.2.2}/LICENSE +0 -0
  11. {supyagent-0.2.1 → supyagent-0.2.2}/README.md +0 -0
  12. {supyagent-0.2.1 → supyagent-0.2.2}/agents/assistant.yaml +0 -0
  13. {supyagent-0.2.1 → supyagent-0.2.2}/agents/coder.yaml +0 -0
  14. {supyagent-0.2.1 → supyagent-0.2.2}/agents/planner.yaml +0 -0
  15. {supyagent-0.2.1 → supyagent-0.2.2}/agents/researcher.yaml +0 -0
  16. {supyagent-0.2.1 → supyagent-0.2.2}/agents/summarizer.yaml +0 -0
  17. {supyagent-0.2.1 → supyagent-0.2.2}/agents/writer.yaml +0 -0
  18. {supyagent-0.2.1 → supyagent-0.2.2}/plans/initial_plan.md +0 -0
  19. {supyagent-0.2.1 → supyagent-0.2.2}/scripts/release.sh +0 -0
  20. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/README.md +0 -0
  21. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_1_foundation.md +0 -0
  22. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_2_sessions.md +0 -0
  23. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_3_repl.md +0 -0
  24. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_4_execution.md +0 -0
  25. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_5_multiagent.md +0 -0
  26. {supyagent-0.2.1 → supyagent-0.2.2}/sprints/sprint_6_polish.md +0 -0
  27. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/__init__.py +0 -0
  28. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/__main__.py +0 -0
  29. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/cli/__init__.py +0 -0
  30. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/__init__.py +0 -0
  31. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/agent.py +0 -0
  32. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/config.py +0 -0
  33. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/context.py +0 -0
  34. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/credentials.py +0 -0
  35. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/delegation.py +0 -0
  36. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/executor.py +0 -0
  37. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/registry.py +0 -0
  38. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/core/session_manager.py +0 -0
  39. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/default_tools/__init__.py +0 -0
  40. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/default_tools/files.py +0 -0
  41. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/default_tools/shell.py +0 -0
  42. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/models/__init__.py +0 -0
  43. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/models/agent_config.py +0 -0
  44. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/models/session.py +0 -0
  45. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/utils/__init__.py +0 -0
  46. {supyagent-0.2.1 → supyagent-0.2.2}/supyagent/utils/paths.py +0 -0
  47. {supyagent-0.2.1 → supyagent-0.2.2}/supypowers/files.py +0 -0
  48. {supyagent-0.2.1 → supyagent-0.2.2}/supypowers/shell.py +0 -0
@@ -38,6 +38,7 @@ ENV/
38
38
  # Environment variables
39
39
  .env
40
40
  .env.local
41
+ .env.supyagent
41
42
 
42
43
  # Test artifacts
43
44
  .pytest_cache/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supyagent
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: LLM agents powered by supypowers - build AI agents with tool use, multi-agent orchestration, and secure credential management
5
5
  Project-URL: Homepage, https://github.com/ergodic-ai/supyagent
6
6
  Project-URL: Documentation, https://github.com/ergodic-ai/supyagent#readme
@@ -0,0 +1,23 @@
1
+ name: tester
2
+ description: A test agent to verify supyagent works
3
+ version: "1.0"
4
+ type: interactive
5
+
6
+ model:
7
+ provider: openrouter/moonshotai/kimi-k2.5
8
+ temperature: 0.7
9
+ max_tokens: 4096
10
+
11
+ system_prompt: |
12
+ You are a helpful AI assistant for testing supyagent.
13
+ You have access to shell commands and file operations.
14
+
15
+ When asked to do something, use the available tools.
16
+ Be concise in your responses.
17
+
18
+ tools:
19
+ allow:
20
+ - "*"
21
+
22
+ limits:
23
+ max_tool_calls_per_turn: 10
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "supyagent"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  description = "LLM agents powered by supypowers - build AI agents with tool use, multi-agent orchestration, and secure credential management"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -25,10 +25,11 @@ from supyagent.default_tools import install_default_tools, list_default_tools
25
25
  from supyagent.models.agent_config import AgentNotFoundError, load_agent_config
26
26
 
27
27
  console = Console()
28
+ console_err = Console(stderr=True)
28
29
 
29
30
 
30
31
  @click.group()
31
- @click.version_option(version="0.2.1", prog_name="supyagent")
32
+ @click.version_option(version="0.2.2", prog_name="supyagent")
32
33
  def cli():
33
34
  """
34
35
  Supyagent - LLM agents powered by supypowers.
@@ -707,15 +708,14 @@ def run(
707
708
  try:
708
709
  config = load_agent_config(agent_name)
709
710
  except AgentNotFoundError as e:
710
- console.print(f"[red]Error:[/red] {e}", err=True)
711
+ console_err.print(f"[red]Error:[/red] {e}")
711
712
  sys.exit(1)
712
713
 
713
714
  # Warn if using interactive agent in execution mode
714
715
  if config.type != "execution" and not quiet:
715
- console.print(
716
+ console_err.print(
716
717
  f"[yellow]Note:[/yellow] '{agent_name}' is an interactive agent. "
717
- "Consider using 'chat' for interactive use.",
718
- err=True,
718
+ "Consider using 'chat' for interactive use."
719
719
  )
720
720
 
721
721
  # Parse secrets
@@ -730,9 +730,7 @@ def run(
730
730
  else:
731
731
  input_path = Path(input_file)
732
732
  if not input_path.exists():
733
- console.print(
734
- f"[red]Error:[/red] File not found: {input_file}", err=True
735
- )
733
+ console_err.print(f"[red]Error:[/red] File not found: {input_file}")
736
734
  sys.exit(1)
737
735
  task_content = input_path.read_text().strip()
738
736
  elif task:
@@ -746,22 +744,21 @@ def run(
746
744
  if not sys.stdin.isatty():
747
745
  task_content = sys.stdin.read().strip()
748
746
  else:
749
- console.print(
747
+ console_err.print(
750
748
  "[red]Error:[/red] No task provided. "
751
- "Use positional argument, --input, or pipe to stdin.",
752
- err=True,
749
+ "Use positional argument, --input, or pipe to stdin."
753
750
  )
754
751
  sys.exit(1)
755
752
 
756
753
  if not task_content:
757
- console.print("[red]Error:[/red] Empty task", err=True)
754
+ console_err.print("[red]Error:[/red] Empty task")
758
755
  sys.exit(1)
759
756
 
760
757
  # Run the agent
761
758
  runner = ExecutionRunner(config)
762
759
 
763
760
  if not quiet:
764
- console.print(f"[dim]Running {agent_name}...[/dim]", err=True)
761
+ console_err.print(f"[dim]Running {agent_name}...[/dim]")
765
762
 
766
763
  result = runner.run(task_content, secrets=secrets_dict, output_format=output_format)
767
764
 
@@ -771,7 +768,7 @@ def run(
771
768
  elif result["ok"]:
772
769
  click.echo(result["data"])
773
770
  else:
774
- console.print(f"[red]Error:[/red] {result['error']}", err=True)
771
+ console_err.print(f"[red]Error:[/red] {result['error']}")
775
772
  sys.exit(1)
776
773
 
777
774
 
@@ -827,7 +824,7 @@ def batch(
827
824
  try:
828
825
  config = load_agent_config(agent_name)
829
826
  except AgentNotFoundError as e:
830
- console.print(f"[red]Error:[/red] {e}", err=True)
827
+ console_err.print(f"[red]Error:[/red] {e}")
831
828
  sys.exit(1)
832
829
 
833
830
  # Parse secrets
@@ -4,9 +4,13 @@ LiteLLM wrapper for unified LLM access.
4
4
 
5
5
  from typing import Any
6
6
 
7
+ import litellm
7
8
  from litellm import completion
8
9
  from litellm.types.utils import ModelResponse
9
10
 
11
+ # Suppress LiteLLM debug messages (e.g., "Provider List: ...")
12
+ litellm.suppress_debug_info = True
13
+
10
14
 
11
15
  class LLMClient:
12
16
  """
@@ -193,43 +193,61 @@ def supypowers_to_openai_tools(sp_tools: list[dict[str, Any]]) -> list[dict[str,
193
193
  Convert supypowers tool definitions to OpenAI function calling format.
194
194
 
195
195
  Supypowers docs output format:
196
- {
197
- "script": "hello",
198
- "function": "hello",
199
- "description": "...",
200
- "input_schema": {...}
201
- }
196
+ [
197
+ {
198
+ "script": "/path/to/script.py",
199
+ "functions": [
200
+ {
201
+ "name": "function_name",
202
+ "description": "...",
203
+ "input_schema": {...}
204
+ }
205
+ ]
206
+ }
207
+ ]
202
208
 
203
209
  OpenAI format:
204
210
  {
205
211
  "type": "function",
206
212
  "function": {
207
- "name": "hello__hello",
213
+ "name": "script__function_name",
208
214
  "description": "...",
209
215
  "parameters": {...}
210
216
  }
211
217
  }
212
218
  """
219
+ import os
220
+
213
221
  openai_tools = []
214
222
 
215
- for sp_tool in sp_tools:
216
- script = sp_tool.get("script", "")
217
- func = sp_tool.get("function", "")
218
- description = sp_tool.get("description", "No description")
219
- input_schema = sp_tool.get("input_schema", {"type": "object", "properties": {}})
220
-
221
- # Use double underscore to join script:function (since : isn't allowed in function names)
222
- name = f"{script}__{func}"
223
-
224
- openai_tool = {
225
- "type": "function",
226
- "function": {
227
- "name": name,
228
- "description": description,
229
- "parameters": input_schema,
230
- },
231
- }
223
+ for script_entry in sp_tools:
224
+ script_path = script_entry.get("script", "")
225
+ functions = script_entry.get("functions", [])
226
+
227
+ # Extract script name from path (e.g., "files" from "/path/to/files.py")
228
+ script_name = os.path.splitext(os.path.basename(script_path))[0]
229
+
230
+ # Skip __init__ files with no functions
231
+ if script_name == "__init__" and not functions:
232
+ continue
233
+
234
+ for func_def in functions:
235
+ func_name = func_def.get("name", "")
236
+ description = func_def.get("description", "No description")
237
+ input_schema = func_def.get("input_schema", {"type": "object", "properties": {}})
238
+
239
+ # Use double underscore to join script:function (since : isn't allowed in function names)
240
+ name = f"{script_name}__{func_name}"
241
+
242
+ openai_tool = {
243
+ "type": "function",
244
+ "function": {
245
+ "name": name,
246
+ "description": description,
247
+ "parameters": input_schema,
248
+ },
249
+ }
232
250
 
233
- openai_tools.append(openai_tool)
251
+ openai_tools.append(openai_tool)
234
252
 
235
253
  return openai_tools
@@ -0,0 +1 @@
1
+ """Supypowers tools for this project."""
@@ -1,6 +0,0 @@
1
- """
2
- Supypowers tools for supyagent.
3
-
4
- This directory contains Python functions that agents can use as tools.
5
- Each function becomes a callable tool via the supypowers framework.
6
- """
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes