Migrating from Python
Practical checklist for porting Python maniac-agents apps to @maniac-ai/agents.
Migrating from Python
This guide adapts the alpha migration notes in packages/agents/docs/migration-alpha.md into actionable steps.
1. Install and import
npm install @maniac-ai/agentsReplace Python imports with ESM subpaths:
| Python | TypeScript |
|---|---|
from maniac_agents import Maniac, run_agent | import { Maniac, runAgent } from "@maniac-ai/agents" |
from maniac_agents.memory import InMemoryMemory | import { InMemoryMemory } from "@maniac-ai/agents/memory" |
from maniac_agents.inference import OpenAICompatibleModel | import { OpenAICompatibleModel } from "@maniac-ai/agents/inference/adapters" |
from maniac_agents.acp import serve_acp_stdio | import { serveAcpStdio } from "@maniac-ai/agents/acp" |
Node 22.5+ with native ESM is recommended.
2. Register tools explicitly
Python can infer tool schemas from callables. TypeScript requires explicit JSON Schema:
// Before (Python mental model)
// @tool
// def search(query: str) -> str: ...
// After (TypeScript)
import { tool } from "@maniac-ai/agents";
const search = tool({
name: "search",
description: "Search the knowledge base.",
inputSchema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"]
},
handler: ({ query }) => `results for ${query}`
});3. Rename entry points
| Python | TypeScript |
|---|---|
run_agent(spec, prompt) | runAgent(spec, prompt) |
run_agent_stream(...) | runAgentStream(...) |
run_agent_resume_stream(...) | runAgentResumeStream(...) |
app.chat(...) | app.chat(...) (same name) |
app.chat_stream(...) | app.chatStream(...) |
Checkpoint payloads, trace events, and tool results deserialize with the same field names — swap method casing only at the call site.
4. Wire permissions and HITL
StaticPermissionPolicy, RuleBasedPolicy, and SessionPermissionCache mirror Python. Pause envelopes include { type: "paused", checkpoint, pending } before the terminal { type: "result", result: { status: "paused" } }.
Resume from checkpoints:
for await (const env of app.resumeCheckpointStream(checkpointId, responses)) {
if (env.type === "event") handleTrace(env.event);
else handleResult(env.result);
}5. Python REPL and memory RPC
No change to the worker protocol. Configure deployment explicitly in packaged apps:
import { PythonSandboxClient } from "@maniac-ai/agents/runtime";
const sandbox = new PythonSandboxClient({
pythonExecutable: "/opt/maniac/.venv/bin/python",
pythonPath: ["/opt/maniac"]
});Python cells still call:
await memory(op="save", content={"note": "hello"})See Python runtime for deployment modes.
6. Background tasks
Replace Maniac(background_tasks=...) with:
new Maniac({
backgroundTasks: {
enabled: true,
global_concurrency: 10,
per_agent_concurrency: 5
}
});bg_list, bg_check, bg_cancel, and bg_wait auto-inject under the same gate conditions as Python. bg_wait uses task_ids: string[] (required) plus mode: "all" | "any".
7. Memory adapters
| Python | TypeScript |
|---|---|
InMemoryMemory | InMemoryMemory |
PostgresMemory | Not ported — use SqliteMemory for local durable storage |
VectorMemory | VectorMemory wrapper |
HonchoMemory | HonchoMemory adapter |
SqliteMemory schema is compatible with the Python Postgres reference layout.
8. Channels (TS-only today)
Slack/Discord/Telegram bots via serveChannels and ChatToolset are TypeScript-only. Python parity is planned. If you rely on chat-platform integrations, migrate the bot host to TypeScript first.
9. Validate with fixtures
Run TS validator tests against packages/agents/fixtures/schema_roundtrip.json and trace_checkpoint.json to confirm your ported serializers match Python golden output before cutting over production traffic.
Remaining gaps
Intentional TS/Python differences to plan around:
- No
acpAgentAsTool/acp_agent_as_toolin TypeScript yet - No
serve_acp_websocketin TypeScript - Channels package is TS-only
- Postgres memory adapter is Python-only; TS ships SqliteMemory instead
See the full parity matrix for per-area status.