SNA

Client agent 네임스페이스

client.agent의 각 메서드 이용법, 입력, 출력 레퍼런스.

Client agent 네임스페이스

client.agent는 실행 중인 coding agent를 제어하는 주 표면입니다. 이 페이지는 모든 public method의 호출 형태, input, return value, 사용 예시, 주의사항을 정리합니다.

Lifecycle 메서드

agent.start(session, config?)

Signature

await client.agent.start(session: string, config?: AgentStartConfig): Promise<{
  status: "started" | "already_running";
  provider: string;
  sessionId: string;
}>

Input

FieldTypeRequiredDescription
sessionstringyes대상 SNA session ID. 없으면 서버가 자동으로 생성합니다.
config.providerstringnoclaude-code, codex, opencode, grok, cursor 같은 runtime id입니다.
config.modelProviderstringno모델 벤더 어트리뷰션 메타데이터입니다. assistant가 작성한 canonical row에 저장됩니다.
config.promptstringno시작 직후 바로 보낼 초기 prompt입니다.
config.modelstringno런타임 모델 slug입니다.
config.permissionModestringnoPermission behavior, for example acceptEdits or bypassPermissions.
config.configDirstringno런타임 config directory override입니다. Claude는 CLAUDE_CONFIG_DIR, Codex는 CODEX_HOME를 사용합니다.
config.forcebooleanno기존 런타임을 종료하고 새로 시작합니다.
config.cwdstringno이 런타임의 작업 디렉토리입니다.
config.historyunknown[]noresume에 사용할 runtime-neutral history입니다.
config.systemPromptstringno기본 system prompt를 교체합니다.
config.appendSystemPromptstringnosystem prompt 뒤에 텍스트를 덧붙입니다.
config.allowedToolsstring[]noagent가 이 tool들만 사용하도록 제한합니다.
config.disallowedToolsstring[]no특정 tool을 차단합니다.
config.mcpServersRecord<string, unknown>noagent에 노출할 MCP server입니다.
config.reasoningLevel`012
config.providerOptionsRecord<string, unknown>no런타임별 option입니다. Codex의 serviceTier, profile, config 등을 전달합니다.
config.extraArgsstring[]nodeprecated된 raw CLI flag입니다. typed field를 우선 사용하세요.

Codex에서는 providerOptionsserviceTier, profile, config를 지정할 수 있습니다. profile--profile <name>으로 전달되고, configcodex app-servercodex exec 양쪽에 반복 가능한 -c key=value override로 전달됩니다.

Returns

FieldDescription
status프로세스를 spawn했다면 started, 세션에 이미 런타임이 있으면 already_running입니다.
provider사용된 런타임입니다.
sessionId런타임 session ID입니다.

Example

const started = await client.agent.start("default", {
  provider: "claude-code",
  model: "claude-sonnet-4-6",
  permissionMode: "acceptEdits",
  cwd: "/Users/me/project",
  reasoningLevel: 3,
});

Notes

  • With HTTP enabled, the promise resolves after the process has been spawned.
  • It does not guarantee the runtime init handshake has reached an idle state. If the UI must wait for readiness, call getStatus until agentStatus === "idle".
  • Calling send immediately after start is safe in normal usage because stdin queues the message.

agent.send(session, message, opts?)

Signature

await client.agent.send(
  session: string,
  message: string,
  opts?: { images?: Array<{ base64: string; mimeType: string }>; meta?: Record<string, unknown> },
): Promise<{ status: "sent" }>

Input

FieldTypeRequiredDescription
sessionstringyes실행 중인 session ID입니다.
messagestringyesagent에 보낼 사용자 message입니다.
opts.images{ base64: string; mimeType: string }[]nomultimodal input을 지원하는 런타임에 전달할 이미지 첨부입니다.
opts.metaRecord<string, unknown>no사용자 message와 함께 저장할 추가 metadata입니다.

Returns

message가 수락되면 { status: "sent" }를 반환합니다. HTTP가 켜져 있으면 promise가 resolve되기 전에 message도 저장됩니다.

Example

await client.agent.send("default", "Please inspect the failing test.");
await client.agent.send("default", "What is in this screenshot?", {
  images: [{ base64: pngBase64, mimeType: "image/png" }],
});

Notes

  • Use this only for stateful interactive sessions.
  • For a stateless one-shot task, use runOnce or runOnceStream.

agent.kill(session)

Signature

await client.agent.kill(session: string): Promise<{ status: "killed" | "no_session" }>

Input: session은 종료할 agent process의 session ID입니다.

Returns: 런타임을 중단했다면 killed, 세션이 없으면 no_session입니다.

Example

await client.agent.kill("default");

Notes: session record는 남고, 실행 중인 process만 종료됩니다.

agent.restart(session, config?)

Signature

await client.agent.restart(session: string, config?: Partial<AgentStartConfig>): Promise<{
  status: "restarted";
  provider: string;
  sessionId: string;
}>

Input: start와 같은 config shape이지만 모든 필드가 optional입니다.

Returns: restart 후 runtime id와 새 runtime session ID를 반환합니다.

Example

await client.agent.restart("default", { model: "claude-opus-4-6" });

Notes: runtime-level 설정을 바꾼 뒤나 CLI process가 비정상 상태가 되었을 때 사용합니다.

agent.interrupt(session)

Signature

await client.agent.interrupt(session: string): Promise<{ status: "interrupted" | "no_session" }>

Use it when 사용자가 stop button을 눌렀지만 다음 message를 위해 session은 유지해야 할 때 사용합니다.

Example

await client.agent.interrupt("default");
await client.agent.send("default", "Try a simpler approach.");

agent.resume(session, opts?)

Signature

await client.agent.resume(session: string, opts?: {
  provider?: string;
  model?: string;
  permissionMode?: string;
  configDir?: string;
  prompt?: string;
  extraArgs?: string[];
  providerOptions?: Record<string, unknown>;
}): Promise<{
  status: "resumed";
  provider: string;
  sessionId: string;
  historyCount: number;
}>

Input

FieldDescription
session저장된 history에서 resume할 session입니다.
opts.provider런타임 override입니다.
opts.model모델 override입니다.
opts.permissionModepermission mode override입니다.
opts.configDir런타임 config directory override입니다.
opts.promptresume 중 보낼 optional prompt입니다.
opts.providerOptions런타임별 option입니다.

Returns

FieldDescription
status성공하면 항상 resumed입니다.
providerresumed session에 사용된 런타임입니다.
sessionId런타임 session ID입니다.
historyCount로드한 persisted message 수입니다.

Example

const resumed = await client.agent.resume("default", { provider: "codex" });
console.log(resumed.historyCount);

agent.getStatus(session)

Signature

await client.agent.getStatus(session: string): Promise<{
  alive: boolean;
  agentStatus: "idle" | "busy" | "disconnected";
  sessionId: string | null;
  ccSessionId: string | null;
  eventCount: number;
  messageCount: number;
  lastMessage: { actor: string; kind: string; content: string; created_at: string } | null;
  config: { provider: string; model: string; permissionMode: string; extraArgs?: string[] } | null;
}>

Use it when runtime state에 의존하는 control을 렌더링하거나 start 이후 준비 상태를 기다릴 때 사용합니다.

Example

const status = await client.agent.getStatus("default");
if (status.alive && status.agentStatus === "idle") {
  await client.agent.send("default", "Next task");
}

One-shot 및 completion 메서드

agent.completion(opts)

Signature

await client.agent.completion(opts: CompletionOptions): Promise<CompletionResult>

Input

FieldTypeRequiredDescription
promptstringyes보낼 prompt입니다.
modelstringno모델 slug입니다.
systemPromptstringnosystem prompt를 교체합니다.
appendSystemPromptstringnosystem prompt 뒤에 덧붙입니다.
labelstringnotrace label입니다.
timeoutnumbernomillisecond 단위 timeout입니다.
extraArgsstring[]nodeprecated된 raw CLI flag입니다.
envRecord<string, string>noenvironment override입니다.
reasoningLevel`012
providerOptionsRecord<string, unknown>no런타임별 option입니다.

Returns

FieldTypeDescription
textstring생성된 text입니다.
usage.inputTokensnumberinput token 수입니다.
usage.outputTokensnumberoutput token 수입니다.
usage.cacheReadTokensnumbercache read token 수입니다.
usage.cacheCreationTokensnumbercache creation token 수입니다.
costUsdnumberUSD 기준 예상 비용입니다.
durationMsnumber전체 소요 시간입니다.
durationApiMsnumber런타임 API 소요 시간입니다.
modelstring사용된 모델입니다.

Example

const result = await client.agent.completion({
  prompt: "Summarize this changelog.",
  model: "claude-haiku-4-5-20251001",
  label: "summary",
});
console.log(result.text, result.costUsd);

Use completion instead of runOnce when 작업에 agent session, tool, event streaming이 필요 없을 때는 runOnce보다 completion을 사용합니다.

agent.runOnce(opts)

Signature

await client.agent.runOnce(opts: RunOnceOptions): Promise<{
  result: string;
  usage: Record<string, unknown> | null;
}>

Input

FieldTypeRequiredDescription
messagestringyes작업 prompt입니다.
modelstringno모델 slug입니다.
systemPromptstringnosystem prompt를 교체합니다.
appendSystemPromptstringnosystem prompt 뒤에 덧붙입니다.
permissionModestringnopermission 동작입니다.
cwdstringno작업 디렉토리입니다.
timeoutnumbernomillisecond 단위 timeout입니다.
providerstringnoruntime id입니다.
extraArgsstring[]nodeprecated된 raw CLI flag입니다.
reasoningLevel`012
providerOptionsRecord<string, unknown>no런타임별 option입니다.

Example

const { result } = await client.agent.runOnce({
  provider: "claude-code",
  message: "Find the most likely cause of the failing build.",
  cwd: process.cwd(),
  timeout: 60_000,
});

Notes: 서버가 temporary session을 만들고 완료를 기다린 뒤 정리합니다.

agent.runOnceStream(opts)

Signature

for await (const event of client.agent.runOnceStream(opts: RunOnceOptions)) {
  // event is Record<string, unknown>
}

Returns: an AsyncGenerator<Record<string, unknown>> of SSE events.

Example

for await (const event of client.agent.runOnceStream({ message: "Explain this file." })) {
  if (event.type === "assistant_delta") process.stdout.write(String(event.delta ?? ""));
  if (event.type === "complete") break;
}

Notes: http: true가 필요하며 POST /agent/run-once/stream을 사용합니다.

Model 및 configuration 메서드

agent.listModels(runtime, config?)

Signature

await client.agent.listModels(runtime: string, config?: ListModelsConfig): Promise<ListModelsResult>

Input

FieldTypeDescription
runtimestring조회할 런타임입니다. 예: claude-code, codex, opencode, grok, cursor.
config.cliPathstring모델 목록 조회에만 쓰는 런타임 CLI 경로 덮어쓰기입니다. 에이전트 spawn 경로는 런처의 runtimePaths를 사용하십시오.
config.refreshbooleancache를 건너뜁니다.

Returns

type ListModelsResult = {
  models: Array<{
    id: string;
    label: string;
    provider: string;
    source: "static" | "api" | "cli";
    contextWindow?: number;
    deprecated?: boolean;
    notes?: string;
  }>;
  source: "static" | "api" | "cli" | "mixed";
  fetchedAt: number;
  error?: string;
};

Example

const catalog = await client.agent.listModels("opencode", { refresh: true });
if (catalog.error) console.warn(catalog.error);

agent.setModel(session, model)

Signature

await client.agent.setModel(session: string, model: string): Promise<{
  status: "updated" | "no_session";
  model: string;
}>

Example

await client.agent.setModel("default", "claude-opus-4-6");

agent.setPermissionMode(session, permissionMode)

Signature

await client.agent.setPermissionMode(session: string, permissionMode: string): Promise<{
  status: "updated" | "no_session";
  permissionMode: string;
}>

Example

await client.agent.setPermissionMode("default", "acceptEdits");

agent.update(session, patch)

Signature

await client.agent.update(
  session: string,
  patch: { cwd?: string; model?: string; permissionMode?: string },
): Promise<{
  status: "updated";
  applied: "in-place" | "respawn";
  runtimeId: string;
  fields: string[];
}>

Example

const updated = await client.agent.update("default", {
  cwd: "/Users/me/other-project",
  model: "gpt-5.5",
});
console.log(updated.applied); // "in-place" or "respawn"

Notes: 일부 런타임은 변경을 in-place로 적용할 수 있습니다. 다른 런타임은 DB-backed history replay를 사용한 respawn이 필요합니다.

Event streaming 메서드

agent.streamEvents(session, since?)

Signature

for await (const event of client.agent.streamEvents(session: string, since?: number)) {
  // event is Record<string, unknown>
}

Use it when WebSocket 대신 SSE를 쓰고 싶을 때 사용합니다. http: true가 필요합니다.

agent.subscribe(session, opts?)

Signature

await client.agent.subscribe(session: string, opts?: {
  since?: number;
  includeHistory?: boolean;
  tail?: number;
}): Promise<{ cursor: number; oldestCursor?: number; hasMore: boolean }>

Input

FieldDescription
since이 event cursor부터 시작합니다.
includeHistorypersisted history를 event로 replay합니다.
tail마지막 N개의 persisted message만 replay합니다. since, includeHistory와 함께 사용할 수 없습니다.

Example

client.agent.onEvent(({ session, cursor, event, isHistory }) => {
  if (!isHistory) renderEvent(session, cursor, event);
});
const sub = await client.agent.subscribe("default", { tail: 20 });

agent.getMessages(session, opts?)

Signature

await client.agent.getMessages(session: string, opts?: {
  before?: number;
  limit?: number;
}): Promise<{
  events: Array<{ cursor: number; event: Record<string, unknown> }>;
  oldestCursor?: number;
  hasMore: boolean;
}>

Use it when 오래된 persisted message를 위한 reverse pagination을 구현할 때 사용합니다.

agent.unsubscribe(session)

Signature

await client.agent.unsubscribe(session: string): Promise<void>

Notes: reconnect resubscription state에서도 해당 session을 제거합니다.

agent.onEvent(handler)

Signature

const unsubscribe = client.agent.onEvent((event: {
  session: string;
  cursor: number;
  event: Record<string, unknown>;
  isHistory?: boolean;
}) => void);

Common event types

TypeMeaning
thinkingagent 내부 reasoning block입니다.
thinking_deltaReasoning을 스트리밍하는 조각입니다.
assistantassistant에게 보이는 response block입니다.
assistant_deltastreaming text fragment입니다.
tool_useagent가 tool을 호출 중입니다.
tool_use_deltaruntime이 제공하는 경우 tool input을 스트리밍하는 조각입니다.
tool_resulttool 실행 결과입니다.
permission_neededruntime이 승인 결정을 기다립니다.
completeturn이 완료되었습니다.
interruptedturn이 정상 완료 전에 중단되었습니다.
errorruntime error입니다.
user_messagemulti-client sync를 위해 echo된 user message입니다.

Permission 메서드

agent.subscribePermissions()

Signature

await client.agent.subscribePermissions(): Promise<{ pendingCount: number }>

Use it when UI가 tool approval prompt를 받아야 할 때 사용합니다. 첫 permission prompt를 놓치면 안 된다면 agent 시작 전에 subscribe하세요.

agent.unsubscribePermissions()

Signature

await client.agent.unsubscribePermissions(): Promise<void>

agent.getPendingPermissions(session?)

Signature

await client.agent.getPendingPermissions(session?: string): Promise<{
  pending: Array<{
    sessionId: string;
    request: Record<string, unknown>;
    createdAt: number;
  }>;
}>

Use it when UI가 reconnect하면서 disconnected 상태에 도착한 prompt를 복구할 때 사용합니다.

agent.respondPermission(session, approved)

Signature

await client.agent.respondPermission(
  session: string,
  approved: boolean,
): Promise<{ status: "approved" | "denied" }>

Example

client.agent.onPermissionRequest(({ session, request }) => {
  const safe = request.tool === "Edit";
  client.agent.respondPermission(session, safe);
});

agent.onPermissionRequest(handler)

Signature

const unsubscribe = client.agent.onPermissionRequest((event: {
  session: string;
  request: Record<string, unknown>;
  createdAt: number;
  isHistory?: boolean;
}) => void);

Use it when 사람의 승인을 받기 위해 modal, notification, command palette prompt를 열 때 사용합니다.

목차