11Advanced DEEPSEEK_API_KEY

HTTP server

Serve a streaming agent over HTTP with Server-Sent Events.

flowchart LR
  C([curl]) -- POST /chat --> H[node:http] --> S[StreamingAgent]
  S -. SSE events .-> C

What it shows

  • Each agent event becomes one data: line.
  • The server uses only node:http; any framework works the same way.

The program

examples/http-server/index.ts
import { createServer } from 'node:http';

import { StreamingAgent } from '@astack-tech/components';
import { ModelProvider } from '@astack-tech/integrations';

const apiKey = process.env['DEEPSEEK_API_KEY'];
if (!apiKey) {
  throw new Error('Set DEEPSEEK_API_KEY to run this example.');
}

const agent = new StreamingAgent({ model: new ModelProvider.Deepseek({ apiKey }) });
const port = Number(process.env['PORT'] ?? 3000);

// POST /chat with a plain-text body. The reply is a stream of Server-Sent Events.
const server = createServer((request, response) => {
  if (request.method !== 'POST' || request.url !== '/chat') {
    response.writeHead(404).end();
    return;
  }

  let body = '';
  request.setEncoding('utf8');
  request.on('data', (chunk: string) => {
    body += chunk;
  });
  request.on('end', () => {
    response.writeHead(200, {
      'content-type': 'text/event-stream',
      'cache-control': 'no-cache',
      connection: 'keep-alive',
    });

    void (async () => {
      try {
        for await (const event of agent.runStream(body)) {
          response.write(`data: ${JSON.stringify(event)}\n\n`);
        }
      } catch {
        // runStream already sent an `error` event before it threw.
      } finally {
        response.end();
      }
    })();
  });
});

server.listen(port, () => {
  console.log(`curl -N -X POST localhost:${String(port)}/chat -d "Explain ports in one line"`);
});

Run it

pnpm install && pnpm build

export DEEPSEEK_API_KEY=sk-...
pnpm --filter @astack-examples/http-server start
CONCEPTStreamingStream agent progress to a terminal, a pipeline or an HTTP client.View the folder on GitHub