Skip to main content
Thank you for helping improve Logicore. Contributions of all kinds are welcome — bug reports, documentation fixes, new providers, new tools, and new skills.

Ways to Contribute

Fix or Clarify Docs

Spot an unclear explanation, a broken example, or a missing concept page? Documentation PRs are always appreciated.

Report Bugs

Open an issue with a minimal, reproducible example. Include your Python version, provider, and the full traceback.

Propose Features

Start with a concise problem statement in a GitHub Discussion before writing code, so we can align on the design early.

Add Providers, Tools, or Skills

Extend the framework’s built-in capabilities by following the structured guides below.

Contribution Workflow

1

Fork and branch

Fork the repository on GitHub, then create a descriptive branch:
git checkout -b feat/add-cohere-provider
# or
git checkout -b fix/ollama-tool-result-handling
Keep one logical change per branch to simplify review.
2

Set up the development environment

Install the package in editable mode together with all development dependencies:
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

pip install -e ".[all,dev]"
The dev extra installs pytest, pytest-asyncio, build, and twine.
3

Run the docs site locally (docs changes only)

If you are editing documentation, start the Mintlify dev server:
npm install
npm run dev
The site is served at http://localhost:3000. Changes to .mdx files hot-reload automatically.
4

Make focused changes

Keep changes small and scoped to a single concern. Avoid bundling unrelated fixes or refactors in the same PR.
5

Run the tests

Run the full test suite before pushing:
pytest tests/ -v
For async tests, pytest-asyncio is already configured. Add new tests for any new behaviour you introduce.
6

Open a pull request

Push your branch and open a PR against main. Include:
  • A short summary of what changed and why
  • Steps to validate the change (e.g., the command to run, expected output)
  • A link to any related issue or discussion

Project Structure

logicore/
├── agents/
│   ├── agent.py            # Full-featured Agent
│   ├── agent_basic.py      # BasicAgent and @tool decorator
│   ├── agent_mcp.py        # MCPAgent
│   ├── agent_smart.py      # SmartAgent
│   └── copilot.py          # CopilotAgent
├── providers/
│   ├── base.py             # LLMProvider abstract base
│   ├── gemini_provider.py
│   ├── groq_provider.py
│   ├── ollama_provider.py
│   ├── azure_provider.py
│   ├── openai_provider.py
│   └── gateway.py          # Unified provider gateway
├── tools/
│   ├── registry.py         # Default tool registry
│   ├── filesystem.py
│   ├── execution.py
│   ├── web.py
│   ├── git.py
│   ├── document.py
│   ├── office_tools.py
│   ├── pdf_tools.py
│   ├── cron_tools.py
│   └── agent_tools.py      # SmartAgent-specific tools
├── memory/
│   ├── storage.py
│   ├── middleware.py
│   └── project_memory.py
├── simplemem/              # LanceDB-backed long-term memory
├── skills/
│   ├── base.py
│   └── loader.py
├── mcp_client.py           # Model Context Protocol client
├── session_manager.py
├── telemetry.py
└── reloader.py             # Hot-reload support

Coding Standards

  • Type hints are required on all public functions and methods. Logicore is fully typed (py.typed marker is present).
  • Docstrings are required on every function that will be callable as an LLM tool. The framework parses them to generate JSON schemas.
  • Use **kwargs in tool function signatures to absorb hallucinated parameters from local models.
  • Follow async/await conventions throughout — all agent interactions are asynchronous.
  • Do not introduce new mandatory dependencies without discussion. Optional capabilities belong behind extras in pyproject.toml.
  • All tests live in tests/ and use pytest with pytest-asyncio for async cases.

How to Add a New Provider

1

Create the provider module

Add a new file under logicore/providers/, for example cohere_provider.py.
2

Subclass LLMProvider

Implement the abstract base class defined in logicore/providers/base.py:
from logicore.providers.base import LLMProvider

class CohereProvider(LLMProvider):
    def __init__(self, model_name: str = "command-r", api_key: str = None, **kwargs):
        self.model_name = model_name
        self.api_key = api_key or os.getenv("COHERE_API_KEY")

    async def chat(self, messages: list, tools: list = None, stream: bool = False, **kwargs):
        # Translate messages + tools into the provider's API format,
        # call the API, normalise the response, and return it.
        ...
At minimum, implement chat(). If the provider supports streaming, handle the stream=True path and invoke the on_token callback from kwargs.get("callbacks", {}).
3

Add an optional dependency

Add the provider’s client library as an optional extra in pyproject.toml:
[project.optional-dependencies]
cohere = ["cohere>=5.0"]
Update the all extra to include it as well.
4

Register the provider string alias

Update logicore/providers/gateway.py so that Agent(llm="cohere") resolves to your new class.
5

Export from the top-level package

Add the new provider to logicore/__init__.py and the __all__ list.
6

Write tests and docs

Add at minimum a smoke test under tests/. Create a provider reference page under docs/concepts/providers/ following the pattern of existing provider pages.

How to Add a New Built-in Tool

1

Choose or create a module

Built-in tools live in logicore/tools/. Add your function to an existing module if it fits a current category, or create a new file (e.g., logicore/tools/calendar.py).
2

Write the function with full docstring and type hints

def create_calendar_event(
    title: str,
    date: str,
    duration_minutes: int = 60,
    **kwargs
) -> dict:
    """
    Creates a calendar event.

    Args:
        title: Event title.
        date: ISO 8601 date string (e.g., "2026-04-01T09:00:00").
        duration_minutes: Duration in minutes. Defaults to 60.

    Returns:
        dict with event id and confirmation details.
    """
    ...
Always include **kwargs to handle hallucinated parameters gracefully.
3

Register in the default registry

Import and add the function to the registry in logicore/tools/registry.py so it is available when an agent calls agent.load_default_tools().
4

Export from the tools package

Add the function to logicore/tools/__init__.py.
5

Add optional dependencies if needed

If the tool requires third-party packages, add them to the tools extra in pyproject.toml.
6

Document the tool

Add an entry to the built-in tools reference page (docs/concepts/tools/tools-built-in.mdx).

How to Add a New Skill

Skills are directory-based packages discovered by SkillLoader. No Python changes to the framework are needed — just a correctly structured directory.
1

Create the skill directory

my-skill/
├── SKILL.md
├── scripts/
│   └── tools.py
└── resources/
Only SKILL.md is required.
2

Write SKILL.md

Use YAML frontmatter followed by natural-language instructions the agent will use:
---
name: release_assistant
description: Helps with release checklist and changelog hygiene
version: 1.0.0
author: your-handle
tags: [release, docs]
requires: [git]
---

When handling release tasks:
1. Validate changed files.
2. Summarize user-facing changes.
3. Propose changelog entries.
Supported metadata fields: name, description, version, author, tags, requires.
3

Add callable tools in scripts/*.py

SkillLoader imports functions from scripts/ and exposes those with docstrings as callable tools:
def summarize_release_notes(text: str) -> str:
    """Summarize release notes into concise bullet points."""
    lines = [line.strip() for line in text.splitlines() if line.strip()]
    return "\n".join(f"- {line}" for line in lines[:6])
4

Place the skill in a discovery path

Put the skill directory anywhere Logicore’s SkillLoader is configured to scan, then load it:
agent.load_skill("release_assistant")

For substantial changes — new agent types, new memory backends, or new architectural features — please open a GitHub Discussion first. This lets maintainers give early design feedback and avoids duplicated effort.

Build docs developers (and LLMs) love