Edgeone Makers Migration logo

Edgeone Makers Migration

OrganizationPopular
TencentEdgeOne
edgeone-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 handlers, or add platform capabilities (context.tools, context.sandbox, context.store). Do NOT trigger for new agent projects (use makers-agents instead).

Overview

PublisherTencentEdgeOne
Repositoryedgeone-makers-tools
Skill nameedgeone-makers-migration
Stars
1.9K
Forks
152
Bundled files
6
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 6 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by TencentEdgeOne on GitHub. Read the source before you install it.

Installation

Install the Edgeone Makers Migration AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/TencentEdgeOne/edgeone-makers-tools.git /tmp/edgeone-makers-tools
mkdir -p .claude/skills
cp -r /tmp/edgeone-makers-tools/skills/edgeone-makers-tools/references/makers-migration .claude/skills/edgeone-makers-migration
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Edgeone Makers Migration in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Edgeone Makers Migration on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Edgeone Makers Migration is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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)

typescript
// ❌ 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)

python
# ❌ 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

BeforeAfter
os.environ.get("OPENAI_API_KEY")ctx.env.get("AI_GATEWAY_API_KEY")
LLM(provider="openai", ...) — LiteLLM dispatchLLM(provider="openai", base_url=ctx.env["AI_GATEWAY_BASE_URL"], ...) — bypass LiteLLM
memory=True on Crewmemory=False + use ctx.store
verbose=Trueverbose=False (events go through crewai_event_bus)
crew.kickoff() (blocking)await asyncio.to_thread(crew.kickoff)
Custom search toolsUse ctx.tools.to_crewai_tools(BaseTool)
Flask/FastAPI handlerasync def handler(ctx):ctx.utils.stream_sse(gen())

edgeone.json

json
{
  "buildCommand": "",
  "outputDirectory": "",
  "agents": {
    "framework": "crewai"
  }
}

Requirements

txt
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/references/python-frameworks/crewai.md for the complete pattern. Detailed before/after: references/crewai-to-makers.md


§3. LangGraph / DeepAgents (Node + Python)

Key changes

BeforeAfter
Direct model creation (new ChatOpenAI(...))Use AI_GATEWAY_* for apiKey/baseURL
MemorySaver (in-memory checkpointer)context.store.langgraphCheckpointer (persistent)
Custom tool functionscontext.tools.toLangChainTools(tool)
agent.stream()SSE via createSSEResponse(gen, signal) (Node) or ctx.utils.stream_sse(gen()) (Python)
thread_id manual managementthread_id = context.conversation_id

Node — edgeone.json

json
{
  "agents": {
    "framework": "langgraph"
  }
}

Python — edgeone.json

json
{
  "buildCommand": "",
  "outputDirectory": "",
  "agents": {
    "framework": "langgraph"
  }
}

Migration steps

  1. Move handler into agents/<name>/index.ts (or .py)
  2. Replace model initialization: use AI_GATEWAY_API_KEY + AI_GATEWAY_BASE_URL
  3. Replace checkpointer: context.store.langgraphCheckpointer instead of MemorySaver
  4. Replace store: context.store.langgraphStore
  5. Replace tools: context.tools.toLangChainTools(tool) instead of custom tool functions
  6. Set thread_id: { configurable: { thread_id: context.conversation_id } }
  7. Replace response with SSE streaming pattern

Node: makers-agents/references/node-frameworks/langgraph.md Python: makers-agents/references/python-frameworks/langgraph.md DeepAgents: makers-agents/references/node-frameworks/deepagents.md Detailed before/after: references/langgraph-to-makers.md, references/deepagents-to-makers.md


§4. OpenAI Agents SDK (Node + Python)

Key changes

BeforeAfter
new OpenAI({ apiKey, baseURL })Read AI_GATEWAY_* from context.env / ctx.env
Runner.run(agent, input, { tools })Tools from context.tools.all() (already OpenAI function format)
Session managementcontext.store.openaiSession(convId) (Node)
Express route responseSSE via createSSEResponse(gen, signal) (Node) or ctx.utils.stream_sse(gen()) (Python)
Model name hardcoded`ctx.env.AI_GATEWAY_MODEL

Node — edgeone.json

json
{
  "agents": {
    "framework": "openai-agents-sdk"
  }
}

Python — edgeone.json

json
{
  "buildCommand": "",
  "outputDirectory": "",
  "agents": {
    "framework": "openai-agents-sdk"
  }
}

Migration steps

  1. Move handler into agents/<name>/index.ts (or .py)
  2. Create OpenAI client from context.env (not process.env)
  3. Replace tools with context.tools.all() (returns OpenAI function tools)
  4. Use context.store.openaiSession(conversationId) for session (Node)
  5. Map stream events to SSE: output_text_deltaai_response, tool_calledtool_call

Node: makers-agents/references/node-frameworks/openai-agents.md Python: makers-agents/references/python-frameworks/openai-agents.md Detailed before/after: references/openai-agents-to-makers.md


§5. Claude Agent SDK (Node + Python)

Key changes

BeforeAfter
ANTHROPIC_API_KEY env varMapped from AI_GATEWAY_* via collectGatewayEnv()
process.envcontext.env injected into query().options.env
Custom MCP toolscontext.tools.toClaudeMcpServer()
Sessioncontext.store.claudeSessionStore() (Node)
Stdout EPIPE crashSwallow EPIPE on process.stdout (Node)
No writable config dirSet CLAUDE_CONFIG_DIR=/tmp/claude-agent-sdk, CLAUDE_CODE_TMPDIR=/tmp

Node — edgeone.json

json
{
  "agents": {
    "framework": "claude-agent-sdk"
  }
}

Python — edgeone.json

json
{
  "buildCommand": "",
  "outputDirectory": "",
  "agents": {
    "framework": "claude-agent-sdk"
  }
}

Migration steps

  1. Move handler into agents/<name>/index.ts (or .py)
  2. Map AI_GATEWAY_*ANTHROPIC_* via collectGatewayEnv(context.env)
  3. Inject env into query({ options: { env: collectGatewayEnv(...) } })
  4. Replace MCP tools: context.tools.toClaudeMcpServer('edgeone', { alwaysLoad: true })
  5. Node only: swallow EPIPE on process.stdout
  6. Set writable config dirs: CLAUDE_CONFIG_DIR=/tmp/claude-agent-sdk, CLAUDE_CODE_TMPDIR=/tmp

Node: makers-agents/references/node-frameworks/claude-sdk.md Python: makers-agents/references/python-frameworks/claude-sdk.md Detailed before/after: references/claude-agent-sdk-to-makers.md


§6. Express / Next.js API Routes (Node)

General migration for any Express-based or Next.js API route agent.

The 7-step conversion

StepBeforeAfter
1. File locationapp/api/chat/route.ts or server/routes/chat.tsagents/chat/index.ts
2. Entry signatureexport async function POST(req) or app.post('/chat', handler)export async function onRequest(context)
3. Body parsingawait req.json()context.request.body (already parsed)
4. Headersreq.headers.get('x-foo')context.request.headers['x-foo']
5. Abort signalreq.signalcontext.request.signal (AbortSignal)
6. Model accessprocess.env.OPENAI_API_KEY → direct callcontext.env.AI_GATEWAY_* → AI Gateway
7. Responseres.json() or return Response.json()SSE stream via createSSEResponse(gen, signal)

Example: Next.js API route → Makers

typescript
// ❌ Before: Next.js (app/api/chat/route.ts)
import { NextRequest } from 'next/server';
import OpenAI from 'openai';

export async function POST(req: NextRequest) {
  const { message } = await req.json();
  const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
  const response = await client.chat.completions.create({
    model: 'gpt-4o',
    messages: [{ role: 'user', content: message }],
    stream: true,
  });
  // ... stream back as Response
}

// ✅ After: EdgeOne Makers (agents/chat/index.ts)
import { createLogger, sseEvent, createSSEResponse } from '../_shared';

export async function onRequest(context: any) {
  const { message } = context.request.body ?? {};
  if (!message) return new Response('Missing message', { status: 400 });

  const signal = context.request.signal as AbortSignal;

  return createSSEResponse(async function* (sig) {
    const response = await fetch(context.env.AI_GATEWAY_BASE_URL + '/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${context.env.AI_GATEWAY_API_KEY}`,
      },
      body: JSON.stringify({
        model: context.env.AI_GATEWAY_MODEL || '@makers/deepseek-v4-flash',
        messages: [{ role: 'user', content: message }],
        stream: true,
      }),
      signal: sig,
    });
    // ... proxy SSE chunks ...
    yield 'data: [DONE]\n\n';
  }, signal);
}

§7. Client-Side Migration

Frontend fetch calls

typescript
// ❌ Before: plain fetch without conversation-id
const response = await fetch('/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ message }),
});

// ✅ After: with makers-conversation-id header
const conversationId = getOrCreateConversationId(); // crypto.randomUUID() + localStorage
const response = await fetch('/chat', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'makers-conversation-id': conversationId,  // ⭐ required for all AI endpoints
  },
  body: JSON.stringify({ message }),
});

/stop endpoint

typescript
// ✅ Always pass conversation_id in body for /stop
await fetch('/stop', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ conversation_id: conversationId }),
});

SSE parsing

typescript
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });

  const lines = buffer.split('\n\n');
  buffer = lines.pop() || '';
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = line.slice(6);
      if (data === '[DONE]') return;
      try {
        const event = JSON.parse(data);
        if (event.type === 'ai_response') { /* display text */ }
        if (event.type === 'tool_call') { /* show tool call */ }
        if (event.type === 'ping') { /* ignore heartbeat */ }
      } catch { /* skip non-JSON */ }
    }
  }
}

§8. Post-Migration Verification

After migration, verify these items before deploying:

  • edgeone makers dev starts without errors
  • /chat endpoint returns SSE stream (not JSON)
  • AI responses work end-to-end (frontend → agent → model → frontend)
  • context.env is used everywhere (grep for process.env / os.environ — none should remain)
  • edgeone.json has correct agents.framework
  • Platform tools (context.tools) work in at least one framework
  • Conversation history persists across requests (via context.store)
  • /stop endpoint cancels active runs
  • Frontend sends makers-conversation-id header

See Also

Detailed before/after reference files

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Edgeone Makers Migration AI skill do?

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).

Why use Edgeone Makers Migration on TypingMind?

Because you install it once and use it with any model. Edgeone Makers Migration is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Edgeone Makers Migration in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/TencentEdgeOne/edgeone-makers-tools/tree/main/skills/edgeone-makers-tools/references/makers-migration. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Edgeone Makers Migration?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Edgeone Makers Migration?

As many as you like. As long as a model supports skills, you can use Edgeone Makers Migration with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Edgeone Makers Migration AI skill free?

It is published on GitHub by TencentEdgeOne. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇