stirrup 0.1.3__py3-none-any.whl → 0.1.4__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.
stirrup/tools/finish.py CHANGED
@@ -1,3 +1,7 @@
1
+ """Simple finish tool with file existence validation."""
2
+
3
+ from __future__ import annotations
4
+
1
5
  from typing import Annotated
2
6
 
3
7
  from pydantic import BaseModel, Field
@@ -15,9 +19,31 @@ class FinishParams(BaseModel):
15
19
  ]
16
20
 
17
21
 
22
+ async def _validating_finish_executor(params: FinishParams) -> ToolResult[ToolUseCountMetadata]:
23
+ """Validates all reported files exist before completing."""
24
+ from stirrup.core.agent import _SESSION_STATE
25
+
26
+ try:
27
+ state = _SESSION_STATE.get(None)
28
+ exec_env = state.exec_env if state else None
29
+ except LookupError:
30
+ exec_env = None
31
+
32
+ if exec_env and params.paths:
33
+ missing = [p for p in params.paths if not await exec_env.file_exists(p)]
34
+ if missing:
35
+ return ToolResult(
36
+ content=f"ERROR: Files do not exist: {missing}. Verify paths and ensure files were saved.",
37
+ metadata=ToolUseCountMetadata(),
38
+ success=False,
39
+ )
40
+
41
+ return ToolResult(content=params.reason, metadata=ToolUseCountMetadata(), success=True)
42
+
43
+
18
44
  SIMPLE_FINISH_TOOL: Tool[FinishParams, ToolUseCountMetadata] = Tool[FinishParams, ToolUseCountMetadata](
19
45
  name=FINISH_TOOL_NAME,
20
46
  description="Signal task completion with a reason. Use when the task is finished or cannot proceed further. Note that you will need a separate turn to finish.",
21
47
  parameters=FinishParams,
22
- executor=lambda params: ToolResult(content=params.reason, metadata=ToolUseCountMetadata(), success=True),
48
+ executor=_validating_finish_executor,
23
49
  )
stirrup/utils/logging.py CHANGED
@@ -23,6 +23,7 @@ from rich.text import Text
23
23
  from rich.tree import Tree
24
24
 
25
25
  from stirrup.core.models import AssistantMessage, ToolMessage, UserMessage, _aggregate_list, aggregate_metadata
26
+ from stirrup.utils.text import truncate_msg
26
27
 
27
28
  __all__ = [
28
29
  "AgentLogger",
@@ -769,11 +770,12 @@ class AgentLogger(AgentLoggerBase):
769
770
  content.append("\n\n")
770
771
  content.append("Tool Calls:\n", style="bold magenta")
771
772
  for tc in assistant_message.tool_calls:
772
- args_parsed = json.loads(tc.arguments)
773
- args_formatted = json.dumps(args_parsed, indent=2, ensure_ascii=False)
774
- args_preview = args_formatted[:1000] + "..." if len(args_formatted) > 1000 else args_formatted
775
773
  content.append(f" 🔧 {tc.name}", style="magenta")
776
- content.append(args_preview, style="dim")
774
+ if tc.arguments and tc.arguments.strip():
775
+ args_parsed = json.loads(tc.arguments)
776
+ args_formatted = json.dumps(args_parsed, indent=2, ensure_ascii=False)
777
+ args_preview = args_formatted[:1000] + "..." if len(args_formatted) > 1000 else args_formatted
778
+ content.append(args_preview, style="dim")
777
779
 
778
780
  # Create and print panel with agent name in title
779
781
  title = f"[bold]AssistantMessage[/bold] │ {self.name} │ Turn {turn}/{max_turns}"
@@ -875,9 +877,8 @@ class AgentLogger(AgentLoggerBase):
875
877
  # Unescape HTML entities (e.g., &lt; -> <, &gt; -> >, &amp; -> &)
876
878
  result_text = html.unescape(result_text)
877
879
 
878
- # Truncate long results
879
- if len(result_text) > 1000:
880
- result_text = result_text[:1000] + "..."
880
+ # Truncate long results (keeps start and end, removes middle)
881
+ result_text = truncate_msg(result_text, 1000)
881
882
 
882
883
  # Format as XML with syntax highlighting
883
884
  content = Syntax(result_text, "xml", theme="monokai", word_wrap=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: stirrup
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: The lightweight foundation for building agents
5
5
  Keywords: ai,agent,llm,openai,anthropic,tools,framework
6
6
  Author: Artificial Analysis, Inc.
@@ -47,17 +47,19 @@ Requires-Dist: pydantic>=2.0.0
47
47
  Requires-Dist: rich>=13.0.0
48
48
  Requires-Dist: tenacity>=5.0.0
49
49
  Requires-Dist: trafilatura>=1.9.0
50
- Requires-Dist: stirrup[litellm,e2b,docker,mcp] ; extra == 'all'
50
+ Requires-Dist: stirrup[litellm,e2b,docker,mcp,browser] ; extra == 'all'
51
+ Requires-Dist: browser-use>=0.11.3 ; extra == 'browser'
51
52
  Requires-Dist: docker>=7.0.0 ; extra == 'docker'
52
53
  Requires-Dist: python-dotenv>=1.0.0 ; extra == 'docker'
53
54
  Requires-Dist: e2b-code-interpreter>=2.3.0 ; extra == 'e2b'
54
55
  Requires-Dist: litellm>=1.79.3 ; extra == 'litellm'
55
56
  Requires-Dist: mcp>=1.9.0 ; extra == 'mcp'
56
57
  Requires-Python: >=3.12
57
- Project-URL: Documentation, https://stirrup.artificialanalysis.ai
58
58
  Project-URL: Homepage, https://github.com/ArtificialAnalysis/Stirrup
59
+ Project-URL: Documentation, https://stirrup.artificialanalysis.ai
59
60
  Project-URL: Repository, https://github.com/ArtificialAnalysis/Stirrup
60
61
  Provides-Extra: all
62
+ Provides-Extra: browser
61
63
  Provides-Extra: docker
62
64
  Provides-Extra: e2b
63
65
  Provides-Extra: litellm
@@ -91,16 +93,16 @@ Stirrup is a lightweight framework, or starting point template, for building age
91
93
 
92
94
  ## Features
93
95
 
94
- - **Essential tools built-in:**
95
- - Online search / web browsing
96
- - Code execution (local, Docker container, E2B sandbox)
97
- - MCP client
98
- - Document input and output
99
- - **Skills system:** Extend agent capabilities with modular, domain-specific instruction packages
100
- - **Flexible tool execution:** A generic `Tool` class allows easy tool definition and extension
101
- - **Context management:** Automatically summarizes conversation history when approaching context limits
102
- - **Flexible provider support:** Pre-built support for OpenAI-compatible APIs and LiteLLM, or bring your own client
103
- - **Multimodal support:** Process images, video, and audio with automatic format conversion
96
+ - 🧪 **Code execution:** Run code locally, in Docker, or in an E2B sandbox
97
+ - 🔎 **Online search / web browsing:** Search and fetch web pages
98
+ - 🔌 **MCP client support:** Connect to MCP servers and use their tools/resources
99
+ - 📄 **Document input and output:** Import files into context and produce file outputs
100
+ - 🧩 **Skills system:** Extend agents with modular, domain-specific instruction packages
101
+ - 🛠️ **Flexible tool execution:** A generic `Tool` interface allows easy tool definition
102
+ - 👤 **Human-in-the-loop:** Includes a built-in user input tool that enables human feedback or clarification during agent execution
103
+ - 🧠 **Context management:** Automatically summarizes conversation history when approaching context limits
104
+ - 🔁 **Flexible provider support:** Pre-built support for OpenAI-compatible APIs, LiteLLM, or bring your own client
105
+ - 🖼️ **Multimodal support:** Process images, video, and audio with automatic format conversion
104
106
 
105
107
  ## Installation
106
108
 
@@ -116,6 +118,7 @@ pip install 'stirrup[litellm]' # or: uv add 'stirrup[litellm]'
116
118
  pip install 'stirrup[docker]' # or: uv add 'stirrup[docker]'
117
119
  pip install 'stirrup[e2b]' # or: uv add 'stirrup[e2b]'
118
120
  pip install 'stirrup[mcp]' # or: uv add 'stirrup[mcp]'
121
+ pip install 'stirrup[browser]' # or: uv add 'stirrup[browser]'
119
122
  ```
120
123
 
121
124
  ## Quick Start
@@ -1,14 +1,15 @@
1
1
  stirrup/__init__.py,sha256=4p5Rw7f_wdxVu1FJTgJROe0aTlnc8tOsainBEzDRGEY,1905
2
- stirrup/clients/__init__.py,sha256=oO8VMHmbUhoxFyC0JLQs_kUFNSRlvTj5xz0FgzBb98E,405
2
+ stirrup/clients/__init__.py,sha256=vHtR1rqK7w9LMWCBJXJde_R1pwdbuj9f6AbAJ4ib3xk,622
3
3
  stirrup/clients/chat_completions_client.py,sha256=P0VOGFQcfLIVf7zCGYbopQDjNVEJlpeLBeGvB87sQQg,7390
4
4
  stirrup/clients/litellm_client.py,sha256=2ZrZKKAEV2dEFs6ze4qBl3it5VwiGH8s7wHVuHdw-uY,5507
5
+ stirrup/clients/open_responses_client.py,sha256=AEM2z_LZhT4hW7VUSFb4mqzV5q_mavnLCwiBTUmt340,15303
5
6
  stirrup/clients/utils.py,sha256=Z_8KiENDZVD9fChUm7PA-RLhvoChswHVQsjrHXlIfkg,5684
6
7
  stirrup/constants.py,sha256=WpVPm2jRN2AqYMyoMYeJimiggoquP7M3IrcHNpduFF4,644
7
8
  stirrup/core/__init__.py,sha256=ReBVl7B9h_FNkZ77vCx2xlfuK1JuQ0yTSXrEgc4tONU,39
8
- stirrup/core/agent.py,sha256=2KxjuCy3scLRc59habPSZyYDCHL9a9--UcdFKYV-86w,56907
9
+ stirrup/core/agent.py,sha256=I-SDjXxUOYSVxowy7SHXP_bjEEZD2JIouNnS7VarmxI,58120
9
10
  stirrup/core/cache.py,sha256=lAbbBJzgYInewoBBPMzNooroU2Q7JbF21riggfdIDa8,16697
10
11
  stirrup/core/exceptions.py,sha256=CzLVAi7Ns-t9BWSkqQUCB7ypVHAesV2s4a09-i0NXyQ,213
11
- stirrup/core/models.py,sha256=qMmpecRIl8sKdUePtoVChKA3rBHxzG8lI4ZvuLFHNzo,22553
12
+ stirrup/core/models.py,sha256=hAwquChulASzwf0yirmsWkfgBEnLTxX9pTAkJ7CwVvM,22591
12
13
  stirrup/prompts/__init__.py,sha256=e4bpTktBaFPuO_bIW5DelGNWtT6_NIUqnD2lRv8n89I,796
13
14
  stirrup/prompts/base_system_prompt.txt,sha256=D_UlDWEnG2yaPCMFrE7IqMHI8VCzi4BZ-GnuL3qs5q4,288
14
15
  stirrup/prompts/message_summarizer.txt,sha256=uQoTxreMuC42rTGSZmoH1Dnj06WrEQb0gLkDvVMhosQ,1173
@@ -16,21 +17,22 @@ stirrup/prompts/message_summarizer_bridge.txt,sha256=sWbfnHtI6RWemBIyQsnqHMGpnU-
16
17
  stirrup/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
18
  stirrup/skills/__init__.py,sha256=BEcmdSskfBzx_QK4eKXECucndIKRjHXzzwwwsaez8k4,700
18
19
  stirrup/skills/skills.py,sha256=qhA3HI55kaRqLyvn_56Cs71833Xacg-8qP7muHrwruE,4282
19
- stirrup/tools/__init__.py,sha256=l8bKHZwPBZfBPgxQfLzOKyyzdfoF86NrgdmxhjYW09s,2790
20
+ stirrup/tools/__init__.py,sha256=TJ3AqPhAkfVPboyMGHscIfq-oUc8brPPVnKtUrf9ICU,2879
21
+ stirrup/tools/browser_use.py,sha256=m7y5F9mO_Qhitmpu6NFh9-wYAxqgXb4_T3VuZdgGInM,21111
20
22
  stirrup/tools/calculator.py,sha256=Cckt-8TtltxtuyY_Hh0wOr8efUzBZzg7rG4dBpvpuRM,1293
21
23
  stirrup/tools/code_backends/__init__.py,sha256=O3Rs76r0YcQ27voTrx_zuhIEFawK3b1TQdKi70MORG8,987
22
- stirrup/tools/code_backends/base.py,sha256=5mQxbHoOvtTdiF1y1aVe4csodaCOGvHaVN5viRnUlUE,17250
23
- stirrup/tools/code_backends/docker.py,sha256=Xx4aBZ1uXVznP0qV4tXL2PMMs-8QEPw1bIPvgPasEGk,30281
24
- stirrup/tools/code_backends/e2b.py,sha256=4I5Aqas-4PVhYgMhIAQh3xcwl_0kGiUpo64UU9-awfE,14921
25
- stirrup/tools/code_backends/local.py,sha256=snzbWHnZkVu1ibLLRyRVmi6U9-8407_A0sKbdDNyTe4,19600
26
- stirrup/tools/finish.py,sha256=zdljSs77zMVkA2AGUfV05QmeLxz6JrwJF_ar02yvsVA,950
24
+ stirrup/tools/code_backends/base.py,sha256=aOX09b4sCxjtFecnnklE_dINIfQ_lH3oYZJ3-N7rCMA,17720
25
+ stirrup/tools/code_backends/docker.py,sha256=6zeOL40peNGu3XGEzP6iwVIZmpr2TjENkllt5DZjHr4,30884
26
+ stirrup/tools/code_backends/e2b.py,sha256=hhaDVOYKxbYHIUhFw5kv-Pri0Sb3a-Weh5Zw5H0tyKM,15396
27
+ stirrup/tools/code_backends/local.py,sha256=6D6QnGYyspQbJ5HOaDke-asGc0-W55p-Nh5ABQkzjG0,20125
28
+ stirrup/tools/finish.py,sha256=xprl0z1N_e-8VddLyEIA9pLeMXjh5A9d4LpkKxhOh5A,1803
27
29
  stirrup/tools/mcp.py,sha256=4wWYae95y8Bs7e36hHwnxRfVVj0PABrsRStw492lLaw,18749
28
30
  stirrup/tools/user_input.py,sha256=XwK14FvRQly3vGwgNzPVGoSXfbco0WWaSVpTDyjV09E,4508
29
31
  stirrup/tools/view_image.py,sha256=zazCpZMtLOD6lplLPYGNQ8JeYfc0oUDJoUUyVAp3AMU,3126
30
32
  stirrup/tools/web.py,sha256=B-zp5i1WhjOOMAlYtnvU3N5hNYnJYm8qVXAtNx_ZaRw,12292
31
33
  stirrup/utils/__init__.py,sha256=4kcuExrphSXqgxRgu1q8_Z6Rrb9aAZpIo4Xq4S9Twuk,230
32
- stirrup/utils/logging.py,sha256=48rCzv7B15jiVM1JlKzwTSnGodbqGSKLlsZi9xRMmVM,35045
34
+ stirrup/utils/logging.py,sha256=vZ7P7MotZnjbTyhMZ0p1YVTGhKQBAXBHOGbku3gEzuk,35166
33
35
  stirrup/utils/text.py,sha256=3lGlcXFzQ-Mclsbu7wJciG3CcHvQ_Sk98tqOZxYLlGw,479
34
- stirrup-0.1.3.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
35
- stirrup-0.1.3.dist-info/METADATA,sha256=EyJEJTRFzLoSXnkBPauFvskBgMwJDJ8O2Vm8HdJPdsI,12862
36
- stirrup-0.1.3.dist-info/RECORD,,
36
+ stirrup-0.1.4.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
37
+ stirrup-0.1.4.dist-info/METADATA,sha256=tJvHDTGB-Tfh4YqJVzyny9GAHqd6aZdqhpYG5apy3p8,13304
38
+ stirrup-0.1.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.22
2
+ Generator: uv 0.9.26
3
3
  Root-Is-Purelib: true
4
- Tag: py3-none-any
4
+ Tag: py3-none-any