/makers-migration
Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK, Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions. Use when the user wants to adapt a standard agent project to run on EdgeOne Makers, convert Express/Next.js API routes to Makers
$ npx -y skills add tencentedgeone/edgeone-pages-skills --skill makers-migration --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/makers-migration
Context preview
The summary Claude sees to decide when to auto-load this skill.
Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK, Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions. Use when the user wants to adapt a standard agent project to run on EdgeOne Makers, convert Express/Next.js API routes to Makers
SKILL.md
makers-migration.SKILL.mdname: makers-migration
description: >-
Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK,
Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions.
Use when the user wants to adapt a standard agent project to run on EdgeOne Makers,
convert Express/Next.js API routes to Makers handlers, or add platform capabilities
(context.tools, context.sandbox, context.store).
Do NOT trigger for new agent projects (use makers-agents instead).
metadata:
author: edgeone
version: "1.0.0"
EdgeOne Makers Migration Guide
Migrate existing AI agent projects to the **EdgeOne Makers** platform format. Covers structural conversion, API adaptation, and platform capability injection.
---
Migration Decision Tree
What type of project are you migrating?
├── Python project
│ ├── Using CrewAI → See §2 CrewAI
│ ├── Using LangChain/LangGraph/DeepAgents → See §3 LangGraph (Python)
│ ├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Python)
│ └── Using Claude Agent SDK → See §5 Claude SDK (Python)
└── Node/TS project
├── Using Express/Next.js API routes → See §6 Express → Makers
├── Using LangGraph/DeepAgents → See §3 LangGraph (Node)
├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Node)
└── Using Claude Agent SDK → See §5 Claude SDK (Node)---
⚠️ Migration Checklist (common to all frameworks)
Before starting framework-specific changes, check these global items:
- [ ] Create `edgeone.json` with correct `agents.framework` and `buildCommand`/`outputDirectory`
- [ ] Move backend code from Express routes / Next.js API routes into `agents/` directory
- [ ] Replace `process.env` / `os.environ` with `context.env` / `ctx.env`
- [ ] Replace `req.headers.get('x')` with `context.request.headers['x']` (Node) or plain dict access (Python)
- [ ] Replace `await req.json()` with `context.request.body` (already parsed)
- [ ] Replace direct model API calls (OpenAI, Anthropic) with `AI_GATEWAY_*` env vars
- [ ] Add SSE streaming for AI endpoints (replace `res.json()` / `return {"data": ...}`)
- [ ] Add `makers-conversation-id` header to frontend fetch calls
- [ ] Wire platform tools through `context.tools` instead of custom tool implementations
- [ ] Wire conversation history through `context.store` instead of in-memory or custom DB
- [ ] If using web_search, set `WSA_API_KEY` env var and use `context.tools.get("web_search")`
- [ ] Set up `edgeone makers dev` for local development
---
§1. Standard API Route → Makers Handler
This is the most common migration pattern. Applies to Express/Next.js API routes, plain HTTP handlers, etc.
Node (Express/Next.js → Makers)
// ❌ Before: Next.js API route (app/api/chat/route.ts)
export async function POST(req: Request) {
const body = await req.json();
const headers = req.headers;
const apiKey = process.env.OPENAI_API_KEY;
// ... LLM call ...
return Response.json({ data: result });
}
// ✅ After: Makers agent handler (agents/chat/index.ts)
export async function onRequest(context: any) {
const body = context.request.body; // already parsed
const conversationId = context.conversation_id; // auto-injected from header
const env = context.env; // context.env, never process.env
// ... LLM call via AI_GATEWAY_* ...
return new Response(JSON.stringify({ data: result }), {
headers: { 'Content-Type': 'application/json' },
});
}Python (Flask/FastAPI → Makers)
# ❌ Before: Flask route
@app.route('/chat', methods=['POST'])
def chat():
body = request.get_json()
api_key = os.environ.get('OPENAI_API_KEY')
# ... LLM call ...
return jsonify({'data': result})
# ✅ After: Makers agent handler (agents/chat/index.py)
async def handler(ctx):
body = ctx.request.body
conversation_id = ctx.conversation_id
api_key = ctx.env.get("AI_GATEWAY_API_KEY")
# ... LLM call via AI_GATEWAY_* ...
return {"data": result}---
§2. CrewAI (Python)
Key changes
| Before | After | |--------|-------| | `os.environ.get("OPENAI_API_KEY")` | `ctx.env.get("AI_GATEWAY_API_KEY")` | | `LLM(provider="openai", ...)` — LiteLLM dispatch | `LLM(provider="openai", base_url=ctx.env["AI_GATEWAY_BASE_URL"], ...)` — bypass LiteLLM | | `memory=True` on Crew | `memory=False` + use `ctx.store` | | `verbose=True` | `verbose=False` (events go through `crewai_event_bus`) | | `crew.kickoff()` (blocking) | `await asyncio.to_thread(crew.kickoff)` | | Custom search tools | Use `ctx.tools.to_crewai_tools(BaseTool)` | | Flask/FastAPI handler | `async def handler(ctx):` → `ctx.utils.stream_sse(gen())` |
edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "crewai"
}
}Requirements
crewai>=1.14.5
openai>=1.50.0
Migration steps
1. Replace Flask/FastAPI entry with `async def handler(ctx):` 2. Read env from `ctx.env`, never `os.environ` 3. Use `LLM(provider="openai", api_key=ctx.env["AI_GATEWAY_API_KEY"], base_url=ctx.env["AI_GATEWAY_BASE_URL"])` 4. Set `Crew(memory=False, verbose=False)` 5. Wrap `crew.kickoff()` in `asyncio.to_thread()` 6. Replace custom tools with `ctx.tools.to_crewai_tools(BaseTool)` 7. Return SSE via `ctx.utils.stream_sse(gen())`
> See [makers-agents/skills/python-frameworks/crewai.md](../skills/makers-agents/references/python-frameworks/crewai.md) for the complete pattern. > Detailed before/after: [references/crewai-to-makers.md](references/crewai-to-makers.md)
---
§3. LangGraph / DeepAgents (Node + Python)
Key changes
| Before | After | |--------|-------| | Direct model creation (`new ChatOpenAI(...)`) | Use `AI_GATEWAY_*` for apiKey/baseURL | | `MemorySaver` (in-memory checkpointer) | `context.store.langgraphCheckpointer` (persistent) | | Custom tool functions | `context.tools.toLangChainTools(tool)` | | `agent.stream()` | SSE via `createSSEResponse(gen, signal)` (Node) or `ctx.utils.stream_sse(gen
Read more
name: makers-migration description: >- Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK, Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions. Use when the user wants to adapt a standard agent project to run on EdgeOne Makers, convert Express/Next.js API routes to Makers handlers, or add platform capabilities (context.tools, context.sandbox, context.store). Do NOT trigger for new agent projects (use makers-agents instead). metadata: author: edgeone version: "1.0.0"
EdgeOne Makers Migration Guide
Migrate existing AI agent projects to the **EdgeOne Makers** platform format. Covers structural conversion, API adaptation, and platform capability injection.
---
Migration Decision Tree
What type of project are you migrating?
├── Python project
│ ├── Using CrewAI → See §2 CrewAI
│ ├── Using LangChain/LangGraph/DeepAgents → See §3 LangGraph (Python)
│ ├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Python)
│ └── Using Claude Agent SDK → See §5 Claude SDK (Python)
└── Node/TS project
├── Using Express/Next.js API routes → See §6 Express → Makers
├── Using LangGraph/DeepAgents → See §3 LangGraph (Node)
├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Node)
└── Using Claude Agent SDK → See §5 Claude SDK (Node)---
⚠️ Migration Checklist (common to all frameworks)
Before starting framework-specific changes, check these global items:
- [ ] Create `edgeone.json` with correct `agents.framework` and `buildCommand`/`outputDirectory`
- [ ] Move backend code from Express routes / Next.js API routes into `agents/` directory
- [ ] Replace `process.env` / `os.environ` with `context.env` / `ctx.env`
- [ ] Replace `req.headers.get('x')` with `context.request.headers['x']` (Node) or plain dict access (Python)
- [ ] Replace `await req.json()` with `context.request.body` (already parsed)
- [ ] Replace direct model API calls (OpenAI, Anthropic) with `AI_GATEWAY_*` env vars
- [ ] Add SSE streaming for AI endpoints (replace `res.json()` / `return {"data": ...}`)
- [ ] Add `makers-conversation-id` header to frontend fetch calls
- [ ] Wire platform tools through `context.tools` instead of custom tool implementations
- [ ] Wire conversation history through `context.store` instead of in-memory or custom DB
- [ ] If using web_search, set `WSA_API_KEY` env var and use `context.tools.get("web_search")`
- [ ] Set up `edgeone makers dev` for local development
---
§1. Standard API Route → Makers Handler
This is the most common migration pattern. Applies to Express/Next.js API routes, plain HTTP handlers, etc.
Node (Express/Next.js → Makers)
// ❌ Before: Next.js API route (app/api/chat/route.ts)
export async function POST(req: Request) {
const body = await req.json();
const headers = req.headers;
const apiKey = process.env.OPENAI_API_KEY;
// ... LLM call ...
return Response.json({ data: result });
}
// ✅ After: Makers agent handler (agents/chat/index.ts)
export async function onRequest(context: any) {
const body = context.request.body; // already parsed
const conversationId = context.conversation_id; // auto-injected from header
const env = context.env; // context.env, never process.env
// ... LLM call via AI_GATEWAY_* ...
return new Response(JSON.stringify({ data: result }), {
headers: { 'Content-Type': 'application/json' },
});
}Python (Flask/FastAPI → Makers)
# ❌ Before: Flask route
@app.route('/chat', methods=['POST'])
def chat():
body = request.get_json()
api_key = os.environ.get('OPENAI_API_KEY')
# ... LLM call ...
return jsonify({'data': result})
# ✅ After: Makers agent handler (agents/chat/index.py)
async def handler(ctx):
body = ctx.request.body
conversation_id = ctx.conversation_id
api_key = ctx.env.get("AI_GATEWAY_API_KEY")
# ... LLM call via AI_GATEWAY_* ...
return {"data": result}---
§2. CrewAI (Python)
Key changes
| Before | After | |--------|-------| | `os.environ.get("OPENAI_API_KEY")` | `ctx.env.get("AI_GATEWAY_API_KEY")` | | `LLM(provider="openai", ...)` — LiteLLM dispatch | `LLM(provider="openai", base_url=ctx.env["AI_GATEWAY_BASE_URL"], ...)` — bypass LiteLLM | | `memory=True` on Crew | `memory=False` + use `ctx.store` | | `verbose=True` | `verbose=False` (events go through `crewai_event_bus`) | | `crew.kickoff()` (blocking) | `await asyncio.to_thread(crew.kickoff)` | | Custom search tools | Use `ctx.tools.to_crewai_tools(BaseTool)` | | Flask/FastAPI handler | `async def handler(ctx):` → `ctx.utils.stream_sse(gen())` |
edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "crewai"
}
}Requirements
crewai>=1.14.5 openai>=1.50.0
Migration steps
1. Replace Flask/FastAPI entry with `async def handler(ctx):` 2. Read env from `ctx.env`, never `os.environ` 3. Use `LLM(provider="openai", api_key=ctx.env["AI_GATEWAY_API_KEY"], base_url=ctx.env["AI_GATEWAY_BASE_URL"])` 4. Set `Crew(memory=False, verbose=False)` 5. Wrap `crew.kickoff()` in `asyncio.to_thread()` 6. Replace custom tools with `ctx.tools.to_crewai_tools(BaseTool)` 7. Return SSE via `ctx.utils.stream_sse(gen())`
> See [makers-agents/skills/python-frameworks/crewai.md](../skills/makers-agents/references/python-frameworks/crewai.md) for the complete pattern. > Detailed before/after: [references/crewai-to-makers.md](references/crewai-to-makers.md)
---
§3. LangGraph / DeepAgents (Node + Python)
Key changes
| Before | After | |--------|-------| | Direct model creation (`new ChatOpenAI(...)`) | Use `AI_GATEWAY_*` for apiKey/baseURL | | `MemorySaver` (in-memory checkpointer) | `context.store.langgraphCheckpointer` (persistent) | | Custom tool functions | `context.tools.toLangChainTools(tool)` | | `agent.stream()` | SSE via `createSSEResponse(gen, signal)` (Node) or `ctx.utils.stream_sse(gen
Official AI Agent Skills for developing and deploying projects on EdgeOne Makers.
Repo: tencentedgeone/edgeone-pages-skills
Other skills on edgeone-makers-tools.
- /makers-agents
This skill guides building AI agent endpoints on EdgeOne Makers — five framework routes (DeepAgents, LangGraph, CrewAI, OpenAI Agents SDK, Claude Agent SDK), platform-injected `context.store` / `context.tools` / `context.sandbox`, conversation_id dual-channel routing, SSE
Open skill - /makers-cli
EdgeOne Makers CLI command reference. Use when running edgeone CLI commands for dev, build, deploy, env management.
Open skill - /makers-cloud-functions
EdgeOne Makers Cloud Functions — Node.js, Go, and Python runtimes. Use when building server-side APIs, Express/Koa patterns, or backend logic.
Open skill - /makers-deploy
This skill deploys frontend and full-stack projects to EdgeOne Makers (Tencent EdgeOne). Trigger this skill whenever deployment is part of the task — whether as the primary intent or a secondary step. Examples: "deploy my app", "publish this site", "push this live", "create a
Open skill - /makers-edge-functions
V8-based lightweight edge functions on EdgeOne Makers. Covers routing, KV storage access, request/response handling, and environment variables at the edge.
Open skill - /makers-env-adaption
Environment-specific adaptation rules for EdgeOne Makers Skills running in sandboxed or restricted AI coding environments (e.g. WorkBuddy). Trigger when: the user is working in WorkBuddy, a sandboxed IDE, or any non-interactive/CI environment where CLI commands may hang or
Open skill

