機能セッション

クローズ

作業を終えたセッションを閉じ、止めるべき実行を terminate し、結果が不明なターンを復旧する

セッションを終える方法は 3 つある。作業を終えたセッションは close で閉じる。今すぐ止める必要があるときは terminate する。terminate によって結果が不明なターンが残ったら、復旧判断をする。開始で作ったセッション(SDK は sessionId、HTTP API は SID)を引き続き使う。

closeterminate復旧判断 close
SDKsessions.closesessions.terminatesessions.recoveryDecisions.create
HTTP APIPOST …/closePOST …/terminatePOST …/recovery-decisions
scopesessions:controlsessions:controlsessions:recover
進行中のターン最後まで実行し、checkpoint を残す実行を強制終了する。ターンが outcome_unknown になることがあるすでに停止したセッションが対象
待機中の入力閉じるときにキャンセル即座にキャンセル即座にキャンセル
結果closed(元に戻せない)stopped(resume 可能)closed(元に戻せない)

close

close は、実行中のターンが終わるまで待つ。まだ開始していないターンはキャンセルされる(cancelled_turn_count)。下の例では、最初のターンが終わった後に閉じる。

import { closeResult, waitForReceipt, waitForTurn } from "@werft-ai/sdk";

await waitForTurn(werft, sessionId, created.turn_id);
const { revision } = await werft.sessions.get(sessionId);
const accepted = await werft.sessions.close(sessionId, {
  expected_revision: revision,
  reason: "work is done",
});
const receipt = await waitForReceipt(werft, accepted.receipt_id);
console.log(receipt.operation, receipt.status, closeResult(receipt));
close succeeded {
  checkpoint_revision: 0,
  cancelled_turn_count: 0,
  resulting_admission_state: 'closed'
}

closeResult は close の receipt の result を型付きで取り出す。開いているリクエストのせいで止まっているかどうかは closeBlocked(session) で見る。

閉じている間、セッションは closing である。開いている権限リクエストや質問があると close が止まる。応答するか interrupt すれば解除される。60 秒を超えると attention が CLOSE_BLOCKED になる。閉じた後のメッセージと pause・resume・close・terminate は 409 SESSION_CLOSED になる。すでに終了したターンを指す interrupt は、閉じた後でも何もしない成功(no_op: true)になる。

terminate

terminate は実行を即座に停止する。ツールがすでに外部に対して行ったことは元に戻さない。待機中のセッションを terminate するとすぐ stopped になり、そのまま resume できる。実行中だったターンがあれば、そのターンは outcome_unknown になり、セッションは復旧判断を待つ。

const runaway = await werft.sessions.create({
  profile_id: "claude-coding-local",
  repository_id: "sample-app",
  message:
    'GATE-SPEC {"id":"runaway","steps":[],"final":"never","finalDelayMs":300000}',
});
const id = runaway.session_id;
while ((await werft.sessions.turns.get(id, runaway.turn_id)).status !== "running") {
  await new Promise((resolve) => setTimeout(resolve, 1000));
}
const current = await werft.sessions.get(id);
const terminated = await werft.sessions.terminate(id, {
  expected_revision: current.revision,
  reason: "runaway turn",
});
console.log(terminated.receipt_status, terminated.external_effects_reverted);
while ((await werft.sessions.get(id)).admission_state !== "recovery_required") {
  await new Promise((resolve) => setTimeout(resolve, 2000));
}
console.log((await werft.sessions.turns.get(id, runaway.turn_id)).status);
accepted false
outcome_unknown

復旧判断

outcome_unknown は成功でも失敗でもない。そのターンが外部に何をしたかを確認した人が判断する。

判断内容
abandonそのターンを cancelled にして、最後の checkpoint から続行できるようにする
confirm_completedcheckpoint がそのターンまで含んでいる場合に、完了したものと認める。evidence_ref が必要
start_fresh以前の会話を破棄し、新しい Claude Code セッションで待機中の入力を実行する
retry_restorecheckpoint の復元失敗の原因を直したうえで、同じ checkpoint からもう一度復元する
closeセッションを終了する。元に戻せない
const stopped = await werft.sessions.get(id);
const decided = await werft.sessions.recoveryDecisions.create(id, {
  decision: "close",
  expected_revision: stopped.revision,
  reason: "nothing to keep",
});
const decision = await waitForReceipt(werft, decided.receipt_id);
console.log(decision.operation, decision.result);
recovery_decision {
  resumable: false,
  checkpoint_revision: null,
  resulting_admission_state: 'closed'
}

キーに sessions:recover が必要である。

abandon と confirm_completed には、対象のターンを target_turn_id として一緒に送る。他の判断では受け付けない(400)。abandon の receipt の result.resumable が true なら、resume で続行する。

次のステップ

このページ