스트리밍 completion
단발 프롬프트의 텍스트를 스트리밍하는 세 가지 방법.
SNA는 단발 호출 스트리밍을 세 가지 형태로 제공합니다. 호스트 (인프로세스 vs 네트워크)와 출력 형태(텍스트 전용 vs 전체 이벤트)에 따라 선택하면 됩니다.
1. 인프로세스, 텍스트 전용: completion({ onDelta })
가장 비용이 낮고 가장 간단한 방식입니다. 자동완성 미리보기나 타자기 UX처럼 텍스트 델타만 필요할 때 사용합니다.
import { completion } from "@sna-sdk/core";
await completion({
prompt: "Draft a commit message for: ...",
provider: "claude-code",
model: "claude-haiku-4-5",
onDelta: (chunk) => process.stdout.write(chunk),
});Promise는 최종 텍스트와 사용량을 함께 resolve합니다. onDelta는 side channel이지
최종 결과의 대체물이 아닙니다.
claude-code, codex, opencode, grok-build, cursor 모두 배선되어
있습니다. OpenCode는 onDelta가 있을 때 prompt_async와 이벤트
스트림으로 전환하고, 없을 때는 오버헤드가 낮은 동기 SDK 경로를 유지합니다.
2. 인프로세스, 전체 이벤트 스트림: runOnce({ onEvent })
단발 실행에서 tool_use / thinking / permission_needed 이벤트도
필요할 때 사용합니다.
import { runOnce } from "@sna-sdk/core/server";
await runOnce(sessionManager, {
message: "List the markdown files and summarize each.",
provider: "codex",
onEvent: (event) => {
if (event.type === "assistant_delta") render(event.delta);
if (event.type === "tool_use") showToolCard(event);
},
});비 텍스트 이벤트가 필요 없으면 onDelta 전용 변형을 사용하면 됩니다.
3. 네트워크: SSE 위의 runOnceStream
@sna-sdk/core를 직접 import할 수 없는 브라우저 / Electron renderer
/ 원격 클라이언트용.
for await (const event of client.agent.runOnceStream({
message: "Draft a commit message for: ...",
})) {
if (event.type === "assistant_delta") write(event.delta as string);
if (event.type === "complete") console.log("usage", event.data);
}POST /agent/run-once/stream (Server-Sent Events) 위에 구현되어 있습니다. 스트림은
실행의 최종 complete / error 이벤트 뒤에 닫힙니다.
어떤 걸 써야 하나
| 상황 | API |
|---|---|
| SNA 서버와 같은 프로세스, 텍스트만 | completion({ onDelta }) |
| 같은 프로세스, 전체 이벤트 스트림 | runOnce({ onEvent }) |
| 원격 (브라우저, 별도 Node 호스트) | runOnceStream() |
| 장기 실행 멀티 턴 UI | 세션을 열고 WS agent.subscribe 사용 |