morphllm
Modular AI subagents for document processing. Built for use with OpenAI-compatible APIs.
How It Works
Subagents follow the "Agents as Tools" pattern—specialized secondary agents that your main agent delegates to for domain-specific tasks:
┌─────────────────────┐
│ MAIN AGENT │
│ │
│ • Orchestrates │
│ • Plans │
│ • Delegates │
└──────────┬──────────┘
│
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ DOCX AGENT │ │ PDF AGENT │ │ YOUR AGENT │
│ │ │ │ │ │
│ "Review this │ │ "Fill out │ │ Domain-specific│
│ contract" │ │ this form" │ │ capabilities │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Track changes │ │ Form filling │ │ Custom tools │
│ Comments │ │ Annotations │ │ & APIs │
│ Document edits │ │ (Coming soon) │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
Installation
pip install morphllm
With OpenAI support:
pip install morphllm[openai]
Available Subagents
| Subagent | Description | Status |
|---|---|---|
| DOCX | Track changes, comments, and document editing | Available |
| Form filling and annotations | Coming Soon |
Quick Start
DOCX Client (Direct API Access)
from subagents.docx import DocxClient
client = DocxClient()
# Upload a document
doc_id = client.upload("contract.docx", user_id="user1", chat_id="chat1")
# Read content
content = client.read(doc_id)
# Add comments and track changes
client.edit(doc_id, "add_comment", para_text="Introduction", comment="Needs citation")
client.edit(doc_id, "insert_text", para_text="Introduction", after=".", new_text=" [1]")
# Download the edited document
client.download(doc_id, "contract_edited.docx")
DOCX Agent (AI-Powered)
from subagents.docx import DocxAgent
agent = DocxAgent(api_key="sk-...")
agent.set_document("userId/chatId/docId")
# Simple completion
response = agent.complete("Review this contract and flag any issues")
print(response)
# Full chat with history
result = agent.chat([
{"role": "user", "content": "Add comments to unclear sections"},
])
print(result["choices"][0]["message"]["content"])
# Streaming
for chunk in agent.chat_stream([
{"role": "user", "content": "Summarize the document"},
]):
delta = chunk.get("choices", [{}])[0].get("delta", {})
if "content" in delta:
print(delta["content"], end="", flush=True)
With OpenAI SDK
from openai import OpenAI
from subagents.docx import DocxAgent
agent = DocxAgent()
openai = OpenAI(**agent.openai_config())
response = openai.chat.completions.create(
model="morph-docx",
messages=[{"role": "user", "content": "Hello!"}],
)
Building Custom Subagents
Extend the base classes:
from subagents.core import BaseClient, BaseAgent
class MyClient(BaseClient):
def _default_api_url(self) -> str:
return "https://my-api.example.com"
def my_method(self):
return self._get("/my-endpoint")
class MyAgent(BaseAgent):
def _default_model(self) -> str:
return "gpt-4"
def _default_instructions(self) -> str:
return "You are a helpful assistant."
def _get_tools(self) -> list:
return [...]
def _execute_tool(self, name: str, args: dict) -> str:
...
Environment Variables
| Variable | Description | Default |
|---|---|---|
DOCX_API_URL |
DOCX service URL | https://api.subagents.com/v1/morph-docx |
MORPH_API_URL |
Chat completions base URL | https://api.subagents.com/v1 |
MORPH_API_KEY |
API key (optional) |
License
MIT
Metadata
Release files for morphllm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| morphllm-0.1.0.tar.gz | 8.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| morphllm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.8 kB
Release files / morphllm-0.1.0.tar.gz
| Download URL | morphllm-0.1.0.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
56d0b7f7535e0f4a0b0e53137b51587c1110f1fec57b1cb51e73b46cd409feef
|
|
BLAKE2b-256 checksum How to use checksums |
9725964712aab0153fec6b9923550f60f5791ec0fe804a2514dd29cb98e417fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / morphllm-0.1.0-py3-none-any.whl
| Download URL | morphllm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a80bde8b0911166d9b76ba465f1c581aef3cbce5d89d5f06ea4186a49621bc6a
|
|
BLAKE2b-256 checksum How to use checksums |
6651f733b8d3eb8cdc706252d6e67278ae05331a67b878cc52ebc0c4a10da07f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for morphllm 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.