Two categories of tools
Custom tools
Python functions you write and register. Logicore generates the JSON schema automatically from type hints and docstrings.
Built-in tools
A full registry of pre-built tools for files, web, code execution, Git, Office documents, PDFs, media, and scheduling.
Automatic schema generation
Logicore parses each registered function and produces a JSON schema the LLM receives alongside the conversation. Nothing is written by hand.Input: Python function
Output: JSON schema sent to the LLM
What gets extracted
| Source | Maps to |
|---|---|
| Function name | "name" field |
| Docstring (first line) | "description" field |
Type hints (str, int, bool, List[x]) | JSON property types |
| Parameters with defaults | Added to "default", removed from required |
**kwargs | Not emitted in schema — absorbs extra LLM arguments |
The **kwargs hallucination guard
Local and smaller models sometimes call a tool with extra parameters that were not in the schema. Without **kwargs, this raises a TypeError and the call fails. With it, unexpected arguments are silently absorbed.
Tool registration
Tools can be registered at initialization or at runtime.- At initialization
- At runtime
- Schema + executor
Internal storage
Logicore stores both the schema (sent to the LLM) and the executor (the callable) in separate structures:Tool execution flow
Schema generation
When a function is registered, Logicore extracts the name, docstring, type hints, and defaults to produce a JSON schema. This schema is sent to the LLM in every subsequent request.
LLM decision
The model reads the user message and the available tool schemas. If a tool is appropriate, it returns a
tool_calls block in its response rather than prose.Approval gate
Before executing, Logicore checks approval. By default, built-in tools are grouped into
SAFE_TOOLS, APPROVAL_REQUIRED_TOOLS, and DANGEROUS_TOOLS. You can provide a custom callback or bypass the gate entirely.Execution
If approved, Logicore looks up the executor, parses the JSON arguments into a Python dict, and calls the function. The return value is stringified and packaged as a
tool role message.Error handling
If the tool function raises an exception, Logicore catches it and sends the error string back to the LLM as the tool result:Multi-turn tool usage
Tool results persist in the conversation history, so the LLM can reference earlier results in subsequent turns:Best practices
Write descriptive docstrings
Write descriptive docstrings
The docstring becomes the tool description the LLM reads. Include
Args and Returns sections so the model understands exactly when and how to call the tool.Always include **kwargs
Always include **kwargs
Absorbs hallucinated parameters from models that add extra arguments not declared in the schema.
Return JSON-serializable types
Return JSON-serializable types
Tool results are serialized to strings before being sent to the LLM. Return
dict, list, str, int, or bool — not custom class instances.Use sensible defaults
Use sensible defaults
Parameters with defaults are marked optional in the schema, reducing how often the LLM needs to guess values.
Conditional tool loading
Conditional tool loading
Load tools based on context to avoid exposing dangerous capabilities unnecessarily.
Performance reference
| Operation | Typical time |
|---|---|
| Schema generation (per tool) | under 1ms |
| Tool selection (LLM decision) | 50–200ms (network-bound) |
| Execution | Depends on tool, usually under 100ms |
| Result formatting | under 1ms |
| Total per tool call | ~100–300ms |