logicsrc/packages/agentswarm/examples/server.mjs
Anthony Ettinger 018a583a00 feat(agentswarm): M1+M3 — embeddable swarm runtime wrapping deepagents
@logicsrc/agentswarm: a self-hosted, framework-agnostic multi-agent runtime
that each app mounts on its own route (e.g. tronbrowser.dev/swarm).

M1 — core:
- createSwarmHandler(): Web (Request)=>Response handler, CORS + validation
- SwarmRunner: injectable engine interface
- createDeepAgentRunner(): deepagents (createDeepAgent) adapter; deepagents +
  @langchain/langgraph are optional peers loaded via dynamic import so the core
  builds/tests with zero heavy deps
- SwarmError + onRequest gate: seam for x402 metering / auth (402/403)

M3 — rubric self-check (deepagents RubricMiddleware is Python-only, so ported
at the runner layer):
- createRubricRunner(): grades output via an injectable judge and revises until
  it passes or maxIterations; passes through untouched when no rubric
- createLLMJudge(): cheap-model grader (lazy langchain initChatModel)

13/13 vitest pass; tsc clean; examples/server.mjs demo verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 17:41:49 +00:00

34 lines
1.3 KiB
JavaScript

// Minimal self-host demo: proves the embeddable handler mounts on a plain
// Node server at /swarm. Uses a mock runner so it runs with zero deps and no
// API key — swap `runner` for `await createDeepAgentRunner({ model })` for real.
//
// npm run build && npm run demo
// curl -s localhost:8787/swarm -d '{"messages":[{"role":"user","content":"hi"}]}'
import { createServer } from "node:http";
import { createSwarmHandler } from "../dist/index.js";
const runner = {
async run({ messages, threadId }) {
const last = messages[messages.length - 1]?.content ?? "";
return {
threadId: threadId ?? `thread_${Date.now()}`,
messages: [...messages, { role: "assistant", content: `echo: ${last}` }],
output: `echo: ${last}`
};
}
};
const handle = createSwarmHandler({ runner });
createServer(async (req, res) => {
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const request = new Request(`http://localhost${req.url}`, {
method: req.method,
headers: req.headers,
body: chunks.length ? Buffer.concat(chunks) : undefined
});
const response = await handle(request);
res.writeHead(response.status, Object.fromEntries(response.headers));
res.end(Buffer.from(await response.arrayBuffer()));
}).listen(8787, () => console.log("agentswarm demo on http://localhost:8787/swarm"));