SNA

스트리밍 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 사용

목차