flowchart LR
Q([question]) --> S[StreamingAgent] -. events .-> C([console])
runStream() yields iteration_start, assistant_message, tool_start, tool_result and completed events.
assistant_message.content is the text so far in the current iteration.
The program
examples/streaming-agent/index.tsimport { StreamingAgent } from '@astack-tech/components';
import { ModelProvider } from '@astack-tech/integrations';
import { createTool } from '@astack-tech/tools';
const apiKey = process.env['DEEPSEEK_API_KEY'];
if (!apiKey) {
throw new Error('Set DEEPSEEK_API_KEY to run this example.');
}
const wordCount = createTool(
'word_count',
'Count the words in a text.',
args => String(args['text']).split(/\s+/).filter(Boolean).length,
{ type: 'object', properties: { text: { type: 'string' } }, required: ['text'] }
);
const agent = new StreamingAgent({
model: new ModelProvider.Deepseek({ apiKey }),
tools: [wordCount],
});
let printed = 0;
for await (const event of agent.runStream('How many words are in "data flows through ports"?')) {
switch (event.type) {
case 'assistant_message': {
const text = event.content ?? '';
process.stdout.write(text.slice(printed));
printed = text.length;
break;
}
case 'tool_start':
console.log(`\n[tool] ${event.toolName ?? ''}`);
break;
case 'tool_result':
console.log(`[result] ${JSON.stringify(event.result)}`);
break;
case 'iteration_start':
printed = 0;
break;
case 'completed':
console.log('\n[done]', event.usage);
break;
case 'model_thinking':
case 'error':
break;
}
}
Run it
pnpm install && pnpm build
export DEEPSEEK_API_KEY=sk-...
pnpm --filter @astack-examples/streaming-agent start
CONCEPTStreamingStream agent progress to a terminal, a pipeline or an HTTP client.View the folder on GitHub