Skip to main content

Common MoDIS-compatible Python tools and tool-call execution helpers

Project description

MoDIS Python Tools

modis-py-tools provides MoDIS-compatible function tool definitions, tool groups, and tool-call execution helpers for Python applications.

The distribution name is modis-py-tools; the import package is modis_tools.

Install

python -m pip install modis-py-tools

Optional web provider dependency:

python -m pip install "modis-py-tools[web]"

Development:

python -m pip install -e ".[dev,web]"
.venv/bin/python -m pytest
.venv/bin/python -m ruff check .
.venv/bin/python -m ruff format --check .
.venv/bin/python -m mypy src
.venv/bin/python -m build

Function Conversion

from modis_tools import function_to_tool

def lookup_order(order_id: str, include_history: bool = False) -> dict:
    """Look up an order.

    Args:
        order_id: Order identifier.
        include_history: Whether to include status history.
    """
    return {"order_id": order_id, "status": "processing"}

tool = function_to_tool(lookup_order, name="orders.lookup")
tool_definition = tool.to_wire()

Registry Execution

from modis_tools import ToolRegistry
from modis_tools.builtins import python_group, shell_group

registry = ToolRegistry()
registry.include(shell_group())
registry.include(python_group())

tool_definitions = registry.definitions()
results = registry.execute_tool_calls(model_tool_calls)
messages = [result.to_chat_message() for result in results]

execute_tool_call() and execute_tool_calls() return failed ToolResult objects by default for unknown tools, invalid arguments, and tool exceptions. Pass raise_on_error=True when the host application should handle exceptions.

For a fuller host integration guide, including unattended pipeline setup and future image generation extension notes, see docs/INTEGRATION.md.

Built-In Tools

from modis_tools.builtins import python_group, shell_group, skills_group, web_group

shell_tools = shell_group()
python_tools = python_group()
skill_tools = skills_group(skill_home="./skills")
web_tools = web_group(api_key="...")

shell.run captures stdout, stderr, exit code, duration, timeout state, working directory, policy decision metadata, and truncation metadata. python.run executes Python source in a subprocess using the current interpreter by default.

Shell and Python tools execute local code. Only expose them in trusted contexts where the caller owns policy, sandboxing, and approval decisions.

Shell tools support host-owned policies. Policies are bound by the application when registering the group and are not exposed as model tool-call parameters.

from modis_tools import ToolRegistry
from modis_tools.builtins import ShellPolicy, shell_group

registry = ToolRegistry()
registry.include(shell_group(policy=ShellPolicy.readonly_project("./")))

Built-in shell policy profiles:

Profile Purpose
trusted_local Backward-compatible default for trusted local use.
disabled Denies every shell request.
restricted Deterministic allowlist for unattended pipelines.
readonly_project Read-oriented argv commands inside one project root.

shell.run accepts exactly one of cmd or argv. cmd executes with shell=True; argv executes with shell=False. Restricted policies should prefer argv mode. Policy controls are guardrails, not a strong OS sandbox; use containers, VMs, or other isolation for untrusted execution.

Skill Tools

Skill support is split into runtime visibility, optional host-owned matching, and tool-based skill use. modis-tools provides the use layer: a registry, a prompt generator, and skills.* tools for progressive loading.

skill_home is required in every mode because all skill files must resolve from a trusted root.

from modis_tools import ToolRegistry
from modis_tools.builtins import skills_group
from modis_tools.skills import SkillRegistry, build_skill_system_prompt

skill_home = "./skills"
registry = ToolRegistry()
registry.include(skills_group(skill_home=skill_home, mode="hybrid"))

skill_registry = SkillRegistry.from_home(skill_home)
system_prompt = build_skill_system_prompt(skill_registry, mode="hybrid")

The skills group exposes:

  • skills.list()
  • skills.read(name)
  • skills.list_resources(name)
  • skills.read_resource(name, path)
  • skills.system_prompt(active_skill=None)

Execution modes:

Mode Behavior
tools_only Models use only skills.* tools to read instructions and resources.
shell_only Prompt tells the model where skill_home is; host shell/file policy must handle access.
hybrid Models use skills.* for reads and policy-gated shell for commands only when needed.

Skill matching is intentionally optional and host-owned. The package defines PromptSkillEvaluator as a protocol, but does not decide when a skill should be used.

Web Tools

The web group exposes:

  • web.search(query, num_results=10, search_type="all", relevance_threshold=0.5, included_sources=None, excluded_sources=None, country_code=None, response_length=None, category=None, start_date=None, end_date=None, max_price=None, fast_mode=False, url_only=False, source_biases=None, instructions=None)
  • web.open(id=None, cursor=-1, loc=-1, num_lines=-1)
  • web.find(pattern, cursor=-1, context_lines=3)

Valyu is the default provider when no provider is supplied. Search uses Valyu search, and direct URL opens use Valyu contents extraction. Opened pages and find results include source ids, URLs, and one-based line ranges so responses can be cited or re-opened later in the same tool session.

from modis_tools import ToolRegistry
from modis_tools.builtins import web_group

registry = ToolRegistry()
registry.include(web_group(api_key="..."))

Search options map to Valyu search controls. For example:

result = registry.execute_tool_call({
    "id": "search_1",
    "type": "function",
    "function": {
        "name": "web.search",
        "arguments": """
        {
          "query": "recent multimodal retrieval papers",
          "num_results": 5,
          "relevance_threshold": 0.45,
          "included_sources": ["valyu/valyu-arxiv"],
          "response_length": "medium",
          "start_date": "2026-04-29",
          "end_date": "2026-05-06",
          "country_code": "US"
        }
        """
    }
})

Default search values are copied from the installed Valyu SDK where exposed:

Option Default Notes
num_results 10 Sent to Valyu as max_num_results.
search_type "all" Valyu scopes are web, proprietary, all, and news.
relevance_threshold 0.5 Set to None to omit the threshold parameter.
included_sources None Valyu source ids or arbitrary URLs.
excluded_sources None Valyu source ids or arbitrary URLs.
country_code None Optional ISO country code.
response_length None Supports short, medium, large, max, integer, or numeric string.
category None Provider-specific category.
start_date / end_date None Optional YYYY-MM-DD bounds.
max_price None Provider cost limit if used.
fast_mode False Sent explicitly.
url_only False Sent explicitly.
source_biases None Optional per-source integer biases.
instructions None Optional provider instructions.

is_tool_call is not exposed to the model; the Valyu provider sends it as True.

Valyu provider metadata that is not part of the normalized result shape, such as scores or ranking fields when returned by the SDK, is preserved in each result's metadata object.

Custom providers implement SearchProvider:

from modis_tools.providers.web import Page, SearchResult

class MyProvider:
    def search(self, query: str, *, num_results: int = 10, **kwargs: object) -> list[SearchResult]:
        return [SearchResult(title="Example", url="https://example.test", content="Page text")]

    def fetch(self, url: str) -> Page:
        return Page(title="Fetched", url=url, markdown="Fetched markdown")

web.open can open prior search results by index/result id/URL, or an arbitrary direct URL. Browser-backed fetching is still kept behind the optional browser extra for future extension.

Live Web Tests

Live web tests are skipped unless VALYU_API_KEY is set and the web extra is installed:

python -m pip install -e ".[dev,web]"
VALYU_API_KEY=... pytest -m live

The broader web quality eval is opt-in because it consumes live provider quota:

VALYU_API_KEY=... MODIS_TOOLS_RUN_WEB_EVAL=1 pytest -m "live and eval" -vv

See docs/WEB_EVAL.md for the current query set and comparison checklist.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

modis_py_tools-0.1.1.tar.gz (31.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

modis_py_tools-0.1.1-py3-none-any.whl (31.8 kB view details)

Uploaded Python 3

File details

Details for the file modis_py_tools-0.1.1.tar.gz.

File metadata

  • Download URL: modis_py_tools-0.1.1.tar.gz
  • Upload date:
  • Size: 31.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for modis_py_tools-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2b82f4c7f4dba9edea98901aa0fe2718f9a991f330ec95513d7fc4e06aeaade7
MD5 7a68390a2c00ba4001e3dc06df0700d9
BLAKE2b-256 141a0a2306ea1b89bd38dac89bee3ee0f5b48810772da9c66ed9667fd6193a0a

See more details on using hashes here.

File details

Details for the file modis_py_tools-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: modis_py_tools-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 31.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for modis_py_tools-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ca3a3633c75420f4c2acdb925c59b6b84567e3de292044bd9632544f48c0b93e
MD5 387c2fb7c7be8d3bee4770b90c25ae23
BLAKE2b-256 530f3455a8ce78528b709280993ad46cc2e114f8c172baf464166f01b5e8d1d8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page