tpmjs/apps/railway-executor
Thomas Davis 198f9f7d1e fix: separate sync discovery from enrichment and harden Railway executor
Sync system was timing out because discovery endpoints (keyword, changes)
also ran schema extraction (~10-15s per tool). Now discovery is fast
(npm metadata + DB writes only) and a new /api/sync/enrich endpoint
handles schema extraction in time-budgeted chunks.

Railway executor was crashing without restarting due to unhandled promise
rejections, no restart policy, and no health checks. Added crash
protection, graceful shutdown, cache size limits, railway.toml with
ALWAYS restart policy, and upgraded Deno from 1.39 to 2.1.9.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 04:49:54 +10:00
..
.gitignore feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
Dockerfile fix: separate sync discovery from enrichment and harden Railway executor 2026-02-09 04:49:54 +10:00
package-lock.json feat: add dynamic tool loading system with Railway executor 2025-12-04 08:25:53 +10:00
package.json chore: update dependencies with compatibility fixes 2026-01-09 22:49:41 +10:00
railway.toml fix: separate sync discovery from enrichment and harden Railway executor 2026-02-09 04:49:54 +10:00
README.md refactor: replace exportName with name throughout codebase 2026-01-14 14:18:36 +10:00
server.js feat: add use cases marketing product with AI-generated content 2026-01-20 16:17:35 +10:00
server.ts fix: separate sync discovery from enrichment and harden Railway executor 2026-02-09 04:49:54 +10:00
start.sh fix: separate sync discovery from enrichment and harden Railway executor 2026-02-09 04:49:54 +10:00

Railway Dynamic Tool Executor

Dynamic tool executor service that runs with --experimental-network-imports to support loading npm packages from esm.sh at runtime.

Features

  • 🔥 Dynamic imports from esm.sh
  • 💾 Module caching for fast repeated loads
  • 🛡️ Validation of AI SDK tool structure
  • 🚀 Remote execution of tools with parameters

Endpoints

GET /health

Health check and cache statistics

POST /load-and-describe

Load a tool from esm.sh and return its schema

Request:

{
  "packageName": "firecrawl-aisdk",
  "name": "webSearchTool",
  "version": "0.7.2",
  "importUrl": "https://esm.sh/firecrawl-aisdk@0.7.2"
}

Response:

{
  "success": true,
  "tool": {
    "name": "webSearchTool",
    "description": "Search the web using Firecrawl",
    "inputSchema": { ... }
  }
}

POST /execute-tool

Execute a tool with parameters

Request:

{
  "packageName": "firecrawl-aisdk",
  "name": "webSearchTool",
  "version": "0.7.2",
  "params": {
    "query": "latest AI news"
  }
}

Response:

{
  "success": true,
  "output": { ... },
  "executionTimeMs": 1234
}

POST /cache/clear

Clear the module cache

GET /cache/stats

Get cache statistics

Local Development

# Install dependencies
npm install

# Start server
npm start

# Server runs on http://localhost:3001

Railway Deployment

This service is designed to run on Railway.

Deploy Steps

  1. Initialize Railway in this directory:
cd apps/railway-executor
railway init
  1. Link to your Railway project:
railway link
  1. Deploy:
railway up
  1. Railway will automatically:
    • Detect Node.js
    • Run npm install
    • Execute npm start (which includes --experimental-network-imports)

Environment Variables

No environment variables required for basic operation. Optional:

  • PORT - Server port (Railway sets this automatically)
  • NODE_ENV - Set to production in Railway

Testing

Test health endpoint:

curl http://localhost:3001/health

Test tool loading:

curl -X POST http://localhost:3001/load-and-describe \
  -H "Content-Type: application/json" \
  -d '{
    "packageName": "@tpmjs/hello",
    "name": "helloWorldTool",
    "version": "0.1.0"
  }'

Test tool execution:

curl -X POST http://localhost:3001/execute-tool \
  -H "Content-Type: application/json" \
  -d '{
    "packageName": "@tpmjs/hello",
    "name": "helloWorldTool",
    "version": "0.1.0",
    "params": {}
  }'

Integration with Playground

The playground app calls this service to load and execute tools dynamically.

Set in playground environment:

RAILWAY_SERVICE_URL=https://your-service.up.railway.app

Or use existing:

SANDBOX_EXECUTOR_URL=https://your-service.up.railway.app