selectools 0.2.0__tar.gz → 0.3.0__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.
Files changed (27) hide show
  1. {selectools-0.2.0/src/selectools.egg-info → selectools-0.3.0}/PKG-INFO +29 -29
  2. {selectools-0.2.0 → selectools-0.3.0}/README.md +27 -27
  3. {selectools-0.2.0 → selectools-0.3.0}/pyproject.toml +4 -4
  4. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/__init__.py +1 -1
  5. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/cli.py +5 -5
  6. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/examples/bbox.py +1 -1
  7. {selectools-0.2.0 → selectools-0.3.0/src/selectools.egg-info}/PKG-INFO +29 -29
  8. selectools-0.3.0/src/selectools.egg-info/SOURCES.txt +22 -0
  9. selectools-0.3.0/src/selectools.egg-info/entry_points.txt +2 -0
  10. selectools-0.3.0/src/selectools.egg-info/top_level.txt +1 -0
  11. {selectools-0.2.0 → selectools-0.3.0}/tests/test_framework.py +7 -7
  12. selectools-0.2.0/src/selectools.egg-info/SOURCES.txt +0 -22
  13. selectools-0.2.0/src/selectools.egg-info/entry_points.txt +0 -2
  14. selectools-0.2.0/src/selectools.egg-info/top_level.txt +0 -1
  15. {selectools-0.2.0 → selectools-0.3.0}/LICENSE +0 -0
  16. {selectools-0.2.0 → selectools-0.3.0}/setup.cfg +0 -0
  17. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/agent.py +0 -0
  18. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/env.py +0 -0
  19. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/parser.py +0 -0
  20. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/prompt.py +0 -0
  21. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/providers/base.py +0 -0
  22. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/providers/openai_provider.py +0 -0
  23. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/providers/stubs.py +0 -0
  24. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/tools.py +0 -0
  25. {selectools-0.2.0/src/toolcalling → selectools-0.3.0/src/selectools}/types.py +0 -0
  26. {selectools-0.2.0 → selectools-0.3.0}/src/selectools.egg-info/dependency_links.txt +0 -0
  27. {selectools-0.2.0 → selectools-0.3.0}/src/selectools.egg-info/requires.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selectools
3
- Version: 0.2.0
4
- Summary: Provider-agnostic tool-calling library with pluggable adapters.
3
+ Version: 0.3.0
4
+ Summary: Build AI agents that call your custom Python functions. Connect LLMs to tools, APIs, and databases with any provider (OpenAI, Anthropic, Gemini).
5
5
  Author-email: Backtrack <engineering@backtrack.app>
6
6
  License: LGPL-3.0-or-later
7
7
  Project-URL: Homepage, https://github.com/johnnichev/selectools
@@ -33,13 +33,13 @@ Requires-Dist: anthropic<1.0.0,>=0.28.0; extra == "providers"
33
33
  Requires-Dist: google-generativeai<1.0.0,>=0.8.3; extra == "providers"
34
34
  Dynamic: license-file
35
35
 
36
- # AI Tool Calling
36
+ # AI Tool Calling - Selectools
37
37
 
38
38
  [![PyPI version](https://badge.fury.io/py/selectools.svg)](https://badge.fury.io/py/selectools)
39
39
  [![License: LGPL v3](https://img.shields.io/badge/License-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
40
40
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
41
41
 
42
- Provider-agnostic Python library for TOOL_CALL-style tool execution across multiple LLM/vision backends. The library exposes typed primitives (`Agent`, `Tool`, `Message`, `Role`), pluggable providers (OpenAI adapter + Anthropic/Gemini/Local), streaming support, a hardened TOOL_CALL parser, prompt template, CLI entrypoint, bounding-box demo tool, and helper examples.
42
+ **Build AI agents that can call your custom Python functions.** Selectools lets you connect LLMs (OpenAI, Anthropic, Gemini) to your own tools and functions. Define what your agent can do—search databases, call APIs, process images, or anything else—and let the LLM decide when and how to use them. Works with any provider, handles errors gracefully, and includes streaming support.
43
43
 
44
44
  ## Why This Library Stands Out
45
45
 
@@ -73,7 +73,7 @@ Built for real-world reliability:
73
73
  ### 🧪 **Testing-Friendly Architecture**
74
74
 
75
75
  - **Local provider** for offline development and testing (no API calls, no costs)
76
- - **Mock injection** for deterministic testing (e.g., `TOOLCALLING_BBOX_MOCK_JSON`)
76
+ - **Mock injection** for deterministic testing (e.g., `SELECTOOLS_BBOX_MOCK_JSON`)
77
77
  - **Fake providers** included for unit testing your agent logic
78
78
  - Clean separation of concerns makes components easy to test in isolation
79
79
 
@@ -83,7 +83,7 @@ Not a framework that takes over your application—a library that integrates int
83
83
 
84
84
  ## What's Included
85
85
 
86
- - Core package at `src/toolcalling/` with agent loop, parser, prompt builder, and provider adapters
86
+ - Core package at `src/selectools/` with agent loop, parser, prompt builder, and provider adapters
87
87
  - Providers: OpenAI plus Anthropic/Gemini/Local sharing the same interface
88
88
  - Library-first examples (see below) and tests with fake providers for schemas, parsing, agent wiring
89
89
  - PyPI-ready metadata (`pyproject.toml`) using a src-layout package
@@ -124,8 +124,8 @@ export GEMINI_API_KEY="your-api-key-here" # Optional
124
124
  ## Usage (Library)
125
125
 
126
126
  ```python
127
- from toolcalling import Agent, AgentConfig, Message, Role, Tool, ToolParameter
128
- from toolcalling.providers.openai_provider import OpenAIProvider
127
+ from selectools import Agent, AgentConfig, Message, Role, Tool, ToolParameter
128
+ from selectools.providers.openai_provider import OpenAIProvider
129
129
 
130
130
  # Define a tool
131
131
  search_tool = Tool(
@@ -145,7 +145,7 @@ print(response.content)
145
145
 
146
146
  - Define tools (`Tool` or `@tool`/`ToolRegistry`), pick a provider, run `Agent.run([...])`.
147
147
  - Add vision by supplying `image_path` on `Message` when the provider supports it.
148
- - For offline/testing: use the Local provider and/or `TOOLCALLING_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
148
+ - For offline/testing: use the Local provider and/or `SELECTOOLS_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
149
149
  - Optional dev helpers (not required for library use): `scripts/smoke_cli.py` for quick provider smokes; `scripts/chat.py` for the vision demo.
150
150
 
151
151
  ## Providers (incl. vision & limits)
@@ -171,8 +171,8 @@ print(response.content)
171
171
  The simplest possible tool—great for testing your setup:
172
172
 
173
173
  ```python
174
- from toolcalling import Agent, AgentConfig, Message, Role, tool
175
- from toolcalling.providers.openai_provider import OpenAIProvider
174
+ from selectools import Agent, AgentConfig, Message, Role, tool
175
+ from selectools.providers.openai_provider import OpenAIProvider
176
176
 
177
177
  @tool(description="Echo input back to user")
178
178
  def echo(text: str) -> str:
@@ -188,8 +188,8 @@ print(resp.content)
188
188
  Build a customer support agent that can search a knowledge base, check order status, and create tickets:
189
189
 
190
190
  ```python
191
- from toolcalling import Agent, AgentConfig, Message, Role, ToolRegistry
192
- from toolcalling.providers.openai_provider import OpenAIProvider
191
+ from selectools import Agent, AgentConfig, Message, Role, ToolRegistry
192
+ from selectools.providers.openai_provider import OpenAIProvider
193
193
  import json
194
194
 
195
195
  registry = ToolRegistry()
@@ -241,9 +241,9 @@ print(response.content)
241
241
  Detect and annotate objects in images using OpenAI Vision:
242
242
 
243
243
  ```python
244
- from toolcalling import Agent, AgentConfig, Message, Role
245
- from toolcalling.examples.bbox import create_bounding_box_tool
246
- from toolcalling.providers.openai_provider import OpenAIProvider
244
+ from selectools import Agent, AgentConfig, Message, Role
245
+ from selectools.examples.bbox import create_bounding_box_tool
246
+ from selectools.providers.openai_provider import OpenAIProvider
247
247
 
248
248
  bbox_tool = create_bounding_box_tool()
249
249
  agent = Agent(
@@ -269,8 +269,8 @@ print(response.content)
269
269
  Chain multiple tools to research a topic, summarize findings, and save results:
270
270
 
271
271
  ```python
272
- from toolcalling import Agent, AgentConfig, Message, Role, tool
273
- from toolcalling.providers.openai_provider import OpenAIProvider
272
+ from selectools import Agent, AgentConfig, Message, Role, tool
273
+ from selectools.providers.openai_provider import OpenAIProvider
274
274
  import json
275
275
 
276
276
  @tool(description="Search academic papers and articles")
@@ -315,8 +315,8 @@ print(response.content)
315
315
  Build responsive UIs with streaming responses:
316
316
 
317
317
  ```python
318
- from toolcalling import Agent, AgentConfig, Message, Role, tool
319
- from toolcalling.providers.openai_provider import OpenAIProvider
318
+ from selectools import Agent, AgentConfig, Message, Role, tool
319
+ from selectools.providers.openai_provider import OpenAIProvider
320
320
  import sys
321
321
 
322
322
  @tool(description="Get current time in a timezone")
@@ -348,9 +348,9 @@ print("\n") # Newline after streaming completes
348
348
  Keep sensitive credentials out of tool signatures using `injected_kwargs`:
349
349
 
350
350
  ```python
351
- from toolcalling import Agent, AgentConfig, Message, Role, Tool
352
- from toolcalling.tools import ToolParameter
353
- from toolcalling.providers.openai_provider import OpenAIProvider
351
+ from selectools import Agent, AgentConfig, Message, Role, Tool
352
+ from selectools.tools import ToolParameter
353
+ from selectools.providers.openai_provider import OpenAIProvider
354
354
  import psycopg2
355
355
 
356
356
  def query_database(sql: str, db_connection) -> str:
@@ -398,8 +398,8 @@ print(response.content)
398
398
  Develop and test without API calls using the Local provider:
399
399
 
400
400
  ```python
401
- from toolcalling import Agent, AgentConfig, Message, Role, tool
402
- from toolcalling.providers.stubs import LocalProvider
401
+ from selectools import Agent, AgentConfig, Message, Role, tool
402
+ from selectools.providers.stubs import LocalProvider
403
403
 
404
404
  @tool(description="Format a todo item with priority")
405
405
  def create_todo(task: str, priority: str = "medium", due_date: str = None) -> str:
@@ -425,10 +425,10 @@ print(response.content)
425
425
  Switch between providers without changing your tool definitions:
426
426
 
427
427
  ```python
428
- from toolcalling import Agent, AgentConfig, Message, Role, tool
429
- from toolcalling.providers.openai_provider import OpenAIProvider
430
- from toolcalling.providers.anthropic_provider import AnthropicProvider
431
- from toolcalling.providers.gemini_provider import GeminiProvider
428
+ from selectools import Agent, AgentConfig, Message, Role, tool
429
+ from selectools.providers.openai_provider import OpenAIProvider
430
+ from selectools.providers.anthropic_provider import AnthropicProvider
431
+ from selectools.providers.gemini_provider import GeminiProvider
432
432
  import os
433
433
 
434
434
  @tool(description="Calculate compound interest")
@@ -1,10 +1,10 @@
1
- # AI Tool Calling
1
+ # AI Tool Calling - Selectools
2
2
 
3
3
  [![PyPI version](https://badge.fury.io/py/selectools.svg)](https://badge.fury.io/py/selectools)
4
4
  [![License: LGPL v3](https://img.shields.io/badge/License-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
5
5
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
6
6
 
7
- Provider-agnostic Python library for TOOL_CALL-style tool execution across multiple LLM/vision backends. The library exposes typed primitives (`Agent`, `Tool`, `Message`, `Role`), pluggable providers (OpenAI adapter + Anthropic/Gemini/Local), streaming support, a hardened TOOL_CALL parser, prompt template, CLI entrypoint, bounding-box demo tool, and helper examples.
7
+ **Build AI agents that can call your custom Python functions.** Selectools lets you connect LLMs (OpenAI, Anthropic, Gemini) to your own tools and functions. Define what your agent can do—search databases, call APIs, process images, or anything else—and let the LLM decide when and how to use them. Works with any provider, handles errors gracefully, and includes streaming support.
8
8
 
9
9
  ## Why This Library Stands Out
10
10
 
@@ -38,7 +38,7 @@ Built for real-world reliability:
38
38
  ### 🧪 **Testing-Friendly Architecture**
39
39
 
40
40
  - **Local provider** for offline development and testing (no API calls, no costs)
41
- - **Mock injection** for deterministic testing (e.g., `TOOLCALLING_BBOX_MOCK_JSON`)
41
+ - **Mock injection** for deterministic testing (e.g., `SELECTOOLS_BBOX_MOCK_JSON`)
42
42
  - **Fake providers** included for unit testing your agent logic
43
43
  - Clean separation of concerns makes components easy to test in isolation
44
44
 
@@ -48,7 +48,7 @@ Not a framework that takes over your application—a library that integrates int
48
48
 
49
49
  ## What's Included
50
50
 
51
- - Core package at `src/toolcalling/` with agent loop, parser, prompt builder, and provider adapters
51
+ - Core package at `src/selectools/` with agent loop, parser, prompt builder, and provider adapters
52
52
  - Providers: OpenAI plus Anthropic/Gemini/Local sharing the same interface
53
53
  - Library-first examples (see below) and tests with fake providers for schemas, parsing, agent wiring
54
54
  - PyPI-ready metadata (`pyproject.toml`) using a src-layout package
@@ -89,8 +89,8 @@ export GEMINI_API_KEY="your-api-key-here" # Optional
89
89
  ## Usage (Library)
90
90
 
91
91
  ```python
92
- from toolcalling import Agent, AgentConfig, Message, Role, Tool, ToolParameter
93
- from toolcalling.providers.openai_provider import OpenAIProvider
92
+ from selectools import Agent, AgentConfig, Message, Role, Tool, ToolParameter
93
+ from selectools.providers.openai_provider import OpenAIProvider
94
94
 
95
95
  # Define a tool
96
96
  search_tool = Tool(
@@ -110,7 +110,7 @@ print(response.content)
110
110
 
111
111
  - Define tools (`Tool` or `@tool`/`ToolRegistry`), pick a provider, run `Agent.run([...])`.
112
112
  - Add vision by supplying `image_path` on `Message` when the provider supports it.
113
- - For offline/testing: use the Local provider and/or `TOOLCALLING_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
113
+ - For offline/testing: use the Local provider and/or `SELECTOOLS_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
114
114
  - Optional dev helpers (not required for library use): `scripts/smoke_cli.py` for quick provider smokes; `scripts/chat.py` for the vision demo.
115
115
 
116
116
  ## Providers (incl. vision & limits)
@@ -136,8 +136,8 @@ print(response.content)
136
136
  The simplest possible tool—great for testing your setup:
137
137
 
138
138
  ```python
139
- from toolcalling import Agent, AgentConfig, Message, Role, tool
140
- from toolcalling.providers.openai_provider import OpenAIProvider
139
+ from selectools import Agent, AgentConfig, Message, Role, tool
140
+ from selectools.providers.openai_provider import OpenAIProvider
141
141
 
142
142
  @tool(description="Echo input back to user")
143
143
  def echo(text: str) -> str:
@@ -153,8 +153,8 @@ print(resp.content)
153
153
  Build a customer support agent that can search a knowledge base, check order status, and create tickets:
154
154
 
155
155
  ```python
156
- from toolcalling import Agent, AgentConfig, Message, Role, ToolRegistry
157
- from toolcalling.providers.openai_provider import OpenAIProvider
156
+ from selectools import Agent, AgentConfig, Message, Role, ToolRegistry
157
+ from selectools.providers.openai_provider import OpenAIProvider
158
158
  import json
159
159
 
160
160
  registry = ToolRegistry()
@@ -206,9 +206,9 @@ print(response.content)
206
206
  Detect and annotate objects in images using OpenAI Vision:
207
207
 
208
208
  ```python
209
- from toolcalling import Agent, AgentConfig, Message, Role
210
- from toolcalling.examples.bbox import create_bounding_box_tool
211
- from toolcalling.providers.openai_provider import OpenAIProvider
209
+ from selectools import Agent, AgentConfig, Message, Role
210
+ from selectools.examples.bbox import create_bounding_box_tool
211
+ from selectools.providers.openai_provider import OpenAIProvider
212
212
 
213
213
  bbox_tool = create_bounding_box_tool()
214
214
  agent = Agent(
@@ -234,8 +234,8 @@ print(response.content)
234
234
  Chain multiple tools to research a topic, summarize findings, and save results:
235
235
 
236
236
  ```python
237
- from toolcalling import Agent, AgentConfig, Message, Role, tool
238
- from toolcalling.providers.openai_provider import OpenAIProvider
237
+ from selectools import Agent, AgentConfig, Message, Role, tool
238
+ from selectools.providers.openai_provider import OpenAIProvider
239
239
  import json
240
240
 
241
241
  @tool(description="Search academic papers and articles")
@@ -280,8 +280,8 @@ print(response.content)
280
280
  Build responsive UIs with streaming responses:
281
281
 
282
282
  ```python
283
- from toolcalling import Agent, AgentConfig, Message, Role, tool
284
- from toolcalling.providers.openai_provider import OpenAIProvider
283
+ from selectools import Agent, AgentConfig, Message, Role, tool
284
+ from selectools.providers.openai_provider import OpenAIProvider
285
285
  import sys
286
286
 
287
287
  @tool(description="Get current time in a timezone")
@@ -313,9 +313,9 @@ print("\n") # Newline after streaming completes
313
313
  Keep sensitive credentials out of tool signatures using `injected_kwargs`:
314
314
 
315
315
  ```python
316
- from toolcalling import Agent, AgentConfig, Message, Role, Tool
317
- from toolcalling.tools import ToolParameter
318
- from toolcalling.providers.openai_provider import OpenAIProvider
316
+ from selectools import Agent, AgentConfig, Message, Role, Tool
317
+ from selectools.tools import ToolParameter
318
+ from selectools.providers.openai_provider import OpenAIProvider
319
319
  import psycopg2
320
320
 
321
321
  def query_database(sql: str, db_connection) -> str:
@@ -363,8 +363,8 @@ print(response.content)
363
363
  Develop and test without API calls using the Local provider:
364
364
 
365
365
  ```python
366
- from toolcalling import Agent, AgentConfig, Message, Role, tool
367
- from toolcalling.providers.stubs import LocalProvider
366
+ from selectools import Agent, AgentConfig, Message, Role, tool
367
+ from selectools.providers.stubs import LocalProvider
368
368
 
369
369
  @tool(description="Format a todo item with priority")
370
370
  def create_todo(task: str, priority: str = "medium", due_date: str = None) -> str:
@@ -390,10 +390,10 @@ print(response.content)
390
390
  Switch between providers without changing your tool definitions:
391
391
 
392
392
  ```python
393
- from toolcalling import Agent, AgentConfig, Message, Role, tool
394
- from toolcalling.providers.openai_provider import OpenAIProvider
395
- from toolcalling.providers.anthropic_provider import AnthropicProvider
396
- from toolcalling.providers.gemini_provider import GeminiProvider
393
+ from selectools import Agent, AgentConfig, Message, Role, tool
394
+ from selectools.providers.openai_provider import OpenAIProvider
395
+ from selectools.providers.anthropic_provider import AnthropicProvider
396
+ from selectools.providers.gemini_provider import GeminiProvider
397
397
  import os
398
398
 
399
399
  @tool(description="Calculate compound interest")
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "selectools"
7
- version = "0.2.0"
8
- description = "Provider-agnostic tool-calling library with pluggable adapters."
7
+ version = "0.3.0"
8
+ description = "Build AI agents that call your custom Python functions. Connect LLMs to tools, APIs, and databases with any provider (OpenAI, Anthropic, Gemini)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  license = {text = "LGPL-3.0-or-later"}
@@ -39,8 +39,8 @@ dev = ["pytest>=7.0.0", "build>=1.2.1", "twine>=5.0.0"]
39
39
  providers = ["anthropic>=0.28.0,<1.0.0", "google-generativeai>=0.8.3,<1.0.0"]
40
40
 
41
41
  [project.scripts]
42
- toolcalling = "toolcalling.cli:main"
42
+ selectools = "selectools.cli:main"
43
43
 
44
44
  [tool.setuptools]
45
45
  package-dir = {"" = "src"}
46
- packages = ["toolcalling", "toolcalling.providers", "toolcalling.examples"]
46
+ packages = ["selectools", "selectools.providers", "selectools.examples"]
@@ -1,4 +1,4 @@
1
- """Public exports for the toolcalling package."""
1
+ """Public exports for the selectools package."""
2
2
 
3
3
  from .agent import Agent, AgentConfig
4
4
  from .types import Message, Role, ToolCall
@@ -1,10 +1,10 @@
1
1
  """
2
- CLI entrypoint for the toolcalling library.
2
+ CLI entrypoint for the selectools library.
3
3
 
4
4
  Examples:
5
- python -m toolcalling.cli list-tools
6
- python -m toolcalling.cli run --provider openai --model gpt-4o --prompt "Search docs" --tool echo
7
- python -m toolcalling.cli run --provider openai --prompt "Find the object" --image assets/environment.png --tool detect_bounding_box
5
+ python -m selectools.cli list-tools
6
+ python -m selectools.cli run --provider openai --model gpt-4o --prompt "Search docs" --tool echo
7
+ python -m selectools.cli run --provider openai --prompt "Find the object" --image assets/environment.png --tool detect_bounding_box
8
8
  """
9
9
 
10
10
  from __future__ import annotations
@@ -132,7 +132,7 @@ def interactive_chat(args, tools: Dict[str, Tool]) -> None:
132
132
 
133
133
 
134
134
  def build_parser() -> argparse.ArgumentParser:
135
- parser = argparse.ArgumentParser(description="Multi-model toolcalling CLI")
135
+ parser = argparse.ArgumentParser(description="Multi-model selectools CLI")
136
136
  subparsers = parser.add_subparsers(dest="command", required=True)
137
137
 
138
138
  list_parser = subparsers.add_parser("list-tools", help="List available tools")
@@ -18,7 +18,7 @@ from ..tools import Tool, ToolParameter
18
18
 
19
19
  PROJECT_ROOT = Path(__file__).resolve().parents[3]
20
20
  ASSETS_DIR = PROJECT_ROOT / "assets"
21
- BBOX_MOCK_ENV = "TOOLCALLING_BBOX_MOCK_JSON"
21
+ BBOX_MOCK_ENV = "SELECTOOLS_BBOX_MOCK_JSON"
22
22
 
23
23
 
24
24
  def _resolve_image_path(image_path: str) -> Path:
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selectools
3
- Version: 0.2.0
4
- Summary: Provider-agnostic tool-calling library with pluggable adapters.
3
+ Version: 0.3.0
4
+ Summary: Build AI agents that call your custom Python functions. Connect LLMs to tools, APIs, and databases with any provider (OpenAI, Anthropic, Gemini).
5
5
  Author-email: Backtrack <engineering@backtrack.app>
6
6
  License: LGPL-3.0-or-later
7
7
  Project-URL: Homepage, https://github.com/johnnichev/selectools
@@ -33,13 +33,13 @@ Requires-Dist: anthropic<1.0.0,>=0.28.0; extra == "providers"
33
33
  Requires-Dist: google-generativeai<1.0.0,>=0.8.3; extra == "providers"
34
34
  Dynamic: license-file
35
35
 
36
- # AI Tool Calling
36
+ # AI Tool Calling - Selectools
37
37
 
38
38
  [![PyPI version](https://badge.fury.io/py/selectools.svg)](https://badge.fury.io/py/selectools)
39
39
  [![License: LGPL v3](https://img.shields.io/badge/License-LGPL_v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
40
40
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
41
41
 
42
- Provider-agnostic Python library for TOOL_CALL-style tool execution across multiple LLM/vision backends. The library exposes typed primitives (`Agent`, `Tool`, `Message`, `Role`), pluggable providers (OpenAI adapter + Anthropic/Gemini/Local), streaming support, a hardened TOOL_CALL parser, prompt template, CLI entrypoint, bounding-box demo tool, and helper examples.
42
+ **Build AI agents that can call your custom Python functions.** Selectools lets you connect LLMs (OpenAI, Anthropic, Gemini) to your own tools and functions. Define what your agent can do—search databases, call APIs, process images, or anything else—and let the LLM decide when and how to use them. Works with any provider, handles errors gracefully, and includes streaming support.
43
43
 
44
44
  ## Why This Library Stands Out
45
45
 
@@ -73,7 +73,7 @@ Built for real-world reliability:
73
73
  ### 🧪 **Testing-Friendly Architecture**
74
74
 
75
75
  - **Local provider** for offline development and testing (no API calls, no costs)
76
- - **Mock injection** for deterministic testing (e.g., `TOOLCALLING_BBOX_MOCK_JSON`)
76
+ - **Mock injection** for deterministic testing (e.g., `SELECTOOLS_BBOX_MOCK_JSON`)
77
77
  - **Fake providers** included for unit testing your agent logic
78
78
  - Clean separation of concerns makes components easy to test in isolation
79
79
 
@@ -83,7 +83,7 @@ Not a framework that takes over your application—a library that integrates int
83
83
 
84
84
  ## What's Included
85
85
 
86
- - Core package at `src/toolcalling/` with agent loop, parser, prompt builder, and provider adapters
86
+ - Core package at `src/selectools/` with agent loop, parser, prompt builder, and provider adapters
87
87
  - Providers: OpenAI plus Anthropic/Gemini/Local sharing the same interface
88
88
  - Library-first examples (see below) and tests with fake providers for schemas, parsing, agent wiring
89
89
  - PyPI-ready metadata (`pyproject.toml`) using a src-layout package
@@ -124,8 +124,8 @@ export GEMINI_API_KEY="your-api-key-here" # Optional
124
124
  ## Usage (Library)
125
125
 
126
126
  ```python
127
- from toolcalling import Agent, AgentConfig, Message, Role, Tool, ToolParameter
128
- from toolcalling.providers.openai_provider import OpenAIProvider
127
+ from selectools import Agent, AgentConfig, Message, Role, Tool, ToolParameter
128
+ from selectools.providers.openai_provider import OpenAIProvider
129
129
 
130
130
  # Define a tool
131
131
  search_tool = Tool(
@@ -145,7 +145,7 @@ print(response.content)
145
145
 
146
146
  - Define tools (`Tool` or `@tool`/`ToolRegistry`), pick a provider, run `Agent.run([...])`.
147
147
  - Add vision by supplying `image_path` on `Message` when the provider supports it.
148
- - For offline/testing: use the Local provider and/or `TOOLCALLING_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
148
+ - For offline/testing: use the Local provider and/or `SELECTOOLS_BBOX_MOCK_JSON=tests/fixtures/bbox_mock.json`.
149
149
  - Optional dev helpers (not required for library use): `scripts/smoke_cli.py` for quick provider smokes; `scripts/chat.py` for the vision demo.
150
150
 
151
151
  ## Providers (incl. vision & limits)
@@ -171,8 +171,8 @@ print(response.content)
171
171
  The simplest possible tool—great for testing your setup:
172
172
 
173
173
  ```python
174
- from toolcalling import Agent, AgentConfig, Message, Role, tool
175
- from toolcalling.providers.openai_provider import OpenAIProvider
174
+ from selectools import Agent, AgentConfig, Message, Role, tool
175
+ from selectools.providers.openai_provider import OpenAIProvider
176
176
 
177
177
  @tool(description="Echo input back to user")
178
178
  def echo(text: str) -> str:
@@ -188,8 +188,8 @@ print(resp.content)
188
188
  Build a customer support agent that can search a knowledge base, check order status, and create tickets:
189
189
 
190
190
  ```python
191
- from toolcalling import Agent, AgentConfig, Message, Role, ToolRegistry
192
- from toolcalling.providers.openai_provider import OpenAIProvider
191
+ from selectools import Agent, AgentConfig, Message, Role, ToolRegistry
192
+ from selectools.providers.openai_provider import OpenAIProvider
193
193
  import json
194
194
 
195
195
  registry = ToolRegistry()
@@ -241,9 +241,9 @@ print(response.content)
241
241
  Detect and annotate objects in images using OpenAI Vision:
242
242
 
243
243
  ```python
244
- from toolcalling import Agent, AgentConfig, Message, Role
245
- from toolcalling.examples.bbox import create_bounding_box_tool
246
- from toolcalling.providers.openai_provider import OpenAIProvider
244
+ from selectools import Agent, AgentConfig, Message, Role
245
+ from selectools.examples.bbox import create_bounding_box_tool
246
+ from selectools.providers.openai_provider import OpenAIProvider
247
247
 
248
248
  bbox_tool = create_bounding_box_tool()
249
249
  agent = Agent(
@@ -269,8 +269,8 @@ print(response.content)
269
269
  Chain multiple tools to research a topic, summarize findings, and save results:
270
270
 
271
271
  ```python
272
- from toolcalling import Agent, AgentConfig, Message, Role, tool
273
- from toolcalling.providers.openai_provider import OpenAIProvider
272
+ from selectools import Agent, AgentConfig, Message, Role, tool
273
+ from selectools.providers.openai_provider import OpenAIProvider
274
274
  import json
275
275
 
276
276
  @tool(description="Search academic papers and articles")
@@ -315,8 +315,8 @@ print(response.content)
315
315
  Build responsive UIs with streaming responses:
316
316
 
317
317
  ```python
318
- from toolcalling import Agent, AgentConfig, Message, Role, tool
319
- from toolcalling.providers.openai_provider import OpenAIProvider
318
+ from selectools import Agent, AgentConfig, Message, Role, tool
319
+ from selectools.providers.openai_provider import OpenAIProvider
320
320
  import sys
321
321
 
322
322
  @tool(description="Get current time in a timezone")
@@ -348,9 +348,9 @@ print("\n") # Newline after streaming completes
348
348
  Keep sensitive credentials out of tool signatures using `injected_kwargs`:
349
349
 
350
350
  ```python
351
- from toolcalling import Agent, AgentConfig, Message, Role, Tool
352
- from toolcalling.tools import ToolParameter
353
- from toolcalling.providers.openai_provider import OpenAIProvider
351
+ from selectools import Agent, AgentConfig, Message, Role, Tool
352
+ from selectools.tools import ToolParameter
353
+ from selectools.providers.openai_provider import OpenAIProvider
354
354
  import psycopg2
355
355
 
356
356
  def query_database(sql: str, db_connection) -> str:
@@ -398,8 +398,8 @@ print(response.content)
398
398
  Develop and test without API calls using the Local provider:
399
399
 
400
400
  ```python
401
- from toolcalling import Agent, AgentConfig, Message, Role, tool
402
- from toolcalling.providers.stubs import LocalProvider
401
+ from selectools import Agent, AgentConfig, Message, Role, tool
402
+ from selectools.providers.stubs import LocalProvider
403
403
 
404
404
  @tool(description="Format a todo item with priority")
405
405
  def create_todo(task: str, priority: str = "medium", due_date: str = None) -> str:
@@ -425,10 +425,10 @@ print(response.content)
425
425
  Switch between providers without changing your tool definitions:
426
426
 
427
427
  ```python
428
- from toolcalling import Agent, AgentConfig, Message, Role, tool
429
- from toolcalling.providers.openai_provider import OpenAIProvider
430
- from toolcalling.providers.anthropic_provider import AnthropicProvider
431
- from toolcalling.providers.gemini_provider import GeminiProvider
428
+ from selectools import Agent, AgentConfig, Message, Role, tool
429
+ from selectools.providers.openai_provider import OpenAIProvider
430
+ from selectools.providers.anthropic_provider import AnthropicProvider
431
+ from selectools.providers.gemini_provider import GeminiProvider
432
432
  import os
433
433
 
434
434
  @tool(description="Calculate compound interest")
@@ -0,0 +1,22 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/selectools/__init__.py
5
+ src/selectools/agent.py
6
+ src/selectools/cli.py
7
+ src/selectools/env.py
8
+ src/selectools/parser.py
9
+ src/selectools/prompt.py
10
+ src/selectools/tools.py
11
+ src/selectools/types.py
12
+ src/selectools.egg-info/PKG-INFO
13
+ src/selectools.egg-info/SOURCES.txt
14
+ src/selectools.egg-info/dependency_links.txt
15
+ src/selectools.egg-info/entry_points.txt
16
+ src/selectools.egg-info/requires.txt
17
+ src/selectools.egg-info/top_level.txt
18
+ src/selectools/examples/bbox.py
19
+ src/selectools/providers/base.py
20
+ src/selectools/providers/openai_provider.py
21
+ src/selectools/providers/stubs.py
22
+ tests/test_framework.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ selectools = selectools.cli:main
@@ -0,0 +1 @@
1
+ selectools
@@ -1,5 +1,5 @@
1
1
  """
2
- Test Suite for the toolcalling library.
2
+ Test Suite for the selectools library.
3
3
 
4
4
  These tests avoid real API calls by using fake providers.
5
5
  """
@@ -23,12 +23,12 @@ if str(SRC_DIR) not in sys.path:
23
23
  sys.path.insert(0, str(SRC_DIR))
24
24
 
25
25
  from agent import Agent, AgentConfig, Message, Role, Tool, ToolParameter
26
- from toolcalling.tools import ToolRegistry
27
- from toolcalling.examples.bbox import BBOX_MOCK_ENV, detect_bounding_box_impl
28
- from toolcalling.parser import ToolCallParser
29
- from toolcalling.providers.base import ProviderError
30
- from toolcalling.providers.stubs import AnthropicProvider, GeminiProvider, LocalProvider
31
- from toolcalling.cli import build_parser, run_agent, _default_tools
26
+ from selectools.tools import ToolRegistry
27
+ from selectools.examples.bbox import BBOX_MOCK_ENV, detect_bounding_box_impl
28
+ from selectools.parser import ToolCallParser
29
+ from selectools.providers.base import ProviderError
30
+ from selectools.providers.stubs import AnthropicProvider, GeminiProvider, LocalProvider
31
+ from selectools.cli import build_parser, run_agent, _default_tools
32
32
 
33
33
 
34
34
  class FakeProvider:
@@ -1,22 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- src/selectools.egg-info/PKG-INFO
5
- src/selectools.egg-info/SOURCES.txt
6
- src/selectools.egg-info/dependency_links.txt
7
- src/selectools.egg-info/entry_points.txt
8
- src/selectools.egg-info/requires.txt
9
- src/selectools.egg-info/top_level.txt
10
- src/toolcalling/__init__.py
11
- src/toolcalling/agent.py
12
- src/toolcalling/cli.py
13
- src/toolcalling/env.py
14
- src/toolcalling/parser.py
15
- src/toolcalling/prompt.py
16
- src/toolcalling/tools.py
17
- src/toolcalling/types.py
18
- src/toolcalling/examples/bbox.py
19
- src/toolcalling/providers/base.py
20
- src/toolcalling/providers/openai_provider.py
21
- src/toolcalling/providers/stubs.py
22
- tests/test_framework.py
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- toolcalling = toolcalling.cli:main
@@ -1 +0,0 @@
1
- toolcalling
File without changes
File without changes