Skip to Content

Session과 Turn

대화형으로 AI 직원을 부를 때는 Deployment를 고르고, Session을 만들고, Turn을 보냅니다. 한 Session은 하나의 Deployment에 고정되며 이전 대화가 이어집니다.

Deployment 조회

  • GET /v1/deployments는 이 키가 부를 수 있는 Deployment 목록을 돌려줍니다. (deployments:read)
  • GET /v1/deployments/{deployment_id}는 이름, 버전, 상태(ACTIVE, RETIRED), 모델 등급(model_tier), 허용 도구, 선언된 결과 계약(outputs), 허용 입력 MIME 형식, 호출 속도 한도를 보여 줍니다.
  • 실제 모델 이름은 노출하지 않고 등급만 표시합니다.

Session 만들기

POST /v1/deployments/{deployment_id}/sessions는 Session과 첫 Turn을 한 번에 만듭니다. sessions:write와 turns:write가 필요하고 Idempotency-Key가 필수입니다.

  • 서버는 접수 기록을 저장한 뒤에 202를 돌려줍니다. 연결이 끊겨도 접수된 Turn은 사라지지 않습니다.
  • 응답(receipt)에는 session_id, turn_id, status, idempotency_expires_at, status_url, events_url이 있고, Location 헤더는 Turn 상세의 상대 주소입니다.
  • 이미 보낸 요청과 같은 키와 같은 본문이면 같은 receipt를 돌려줍니다. 같은 키에 다른 본문이면 409 IDEMPOTENCY_CONFLICT입니다.
  • receipt는 최소 24시간(idempotency_expires_at), 그리고 해당 Turn이 끝나기 전까지 보존됩니다.

후속 Turn

POST /v1/sessions/{session_id}/turns로 같은 Session에 새 입력을 보냅니다.

  • 같은 Session에는 한 번에 하나의 Turn만 실행됩니다. 앞선 Turn이 끝나기 전에 보내면 409 SESSION_BUSY입니다. 대기열은 없으니 종결을 확인한 뒤 보내세요.
  • 닫힌 Session에 보내면 409 SESSION_CLOSED입니다.
  • 서로 다른 Session은 병렬로 실행됩니다. 단, Project의 동시 실행 한도가 있습니다.
{ "error": { "code": "SESSION_BUSY", "message": "The session already has an active turn", "retryable": false, "request_id": "0b7b8f0e-0000-4000-8000-000000000004", "details": {} } }

조회, 취소, 닫기, 삭제

경로설명
GET /v1/sessions/{session_id}Session 상태(ACTIVE, CLOSED)와 진행 중 Turn
GET /v1/sessions/{session_id}/turnsTurn 목록. after, limit 커서
GET /v1/sessions/{session_id}/turns/{turn_id}Turn 상태, 사용량, 오류, 결과(outputs), next_cursor
GET /v1/sessions/{session_id}/items공개 Item 기록
POST /v1/sessions/{session_id}/turns/{turn_id}/cancelTurn 취소. 새 취소는 202, 이미 끝났으면 200
POST /v1/sessions/{session_id}/close유휴 Session을 닫음. 실행 중이면 409
DELETE /v1/sessions/{session_id}삭제 접수(202). 이후 내용 조회는 즉시 404

Turn 상태는 QUEUED, RUNNING, REQUIRES_ACTION, CANCEL_REQUESTED, SUCCEEDED, FAILED, CANCELED, EXPIRED입니다. SUCCEEDED, FAILED, CANCELED, EXPIRED가 종결 상태입니다. 실패한 Turn도 접수는 성공한 것이므로 실패 이유는 응답의 error.code로 확인합니다.

  • 취소는 의도를 먼저 저장하며, 이미 끝난 외부 효과는 되돌리지 않습니다. 취소와 완료가 겹치면 먼저 끝난 쪽이 최종 상태가 됩니다.
  • 삭제는 한도와 데이터의 삭제 설명을 보세요.
  • 요청 헤더 X-Correlation-Id(영문, 숫자, 점, 밑줄, 콜론, 하이픈, 1~128자)를 붙이면 호출자 쪽 추적에 쓸 수 있습니다. 형식이 틀리면 400 INVALID_CORRELATION_ID입니다.

입력 형식

{ "input": [ {"type": "TEXT", "text": "Compare the attached report with last month."}, {"type": "FILE", "file_id": "d3c1b8a0-0000-4000-8000-000000000003"} ], "metadata": {"request_ref": "example-001"}, "limits": {"queue_seconds": 600, "execution_seconds": 3600, "max_su": 50} }
  • input은 TEXT와 FILE 항목의 배열입니다. TEXT는 빈 문자열이나 공백만 있는 값이 안 됩니다. 여러 TEXT는 순서대로 줄바꿈을 넣어 실행합니다.
  • FILE의 file_id는 먼저 POST /v1/files로 올려서 받은 값입니다. 한 번 어떤 Session이나 Run에 결속한 파일은 다른 실행에 다시 쓸 수 없으니 새로 올리세요.
  • metadata는 최대 16개 키이며, 키는 1~64자, 문자열 값은 최대 512자입니다.
  • limits는 선택입니다. queue_seconds는 1600, execution_seconds는 13600, max_su는 0 초과 100 이하(소수 8자리까지)입니다. 상한을 넘으면 조용히 줄이지 않고 422 LIMIT_OUT_OF_RANGE로 거절합니다.
  • 요청 JSON 본문은 UTF-8로 64KiB까지입니다. 넘으면 413 INPUT_TOO_LARGE입니다. 모델, 프롬프트, 도구 같은 선언되지 않은 필드는 422 INVALID_INPUT입니다.
  • 파일은 개당 20MiB, 한 입력에 최대 20개입니다. 허용 MIME 형식은 Deployment마다 다릅니다.

출력 형식

Turn 상세의 outputs는 아래 네 가지 형식 중 하나씩입니다.

[ {"id": "o1", "key": "answer", "type": "TEXT", "visibility": "FINAL", "availability": "READY", "item_id": "i1", "text": "Done."}, {"id": "o2", "key": "summary", "type": "JSON", "visibility": "FINAL", "availability": "READY", "schema_ref": "summary", "data": {"count": 3}}, {"id": "o3", "key": "report", "type": "FILE", "visibility": "FINAL", "availability": "READY", "artifact_id": "a1", "filename": "report.txt", "mime_type": "text/plain", "size_bytes": 1024, "sha256": "..."}, {"id": "o4", "key": "reference", "type": "URL", "visibility": "FINAL", "availability": "READY", "url": "https://example.com/report", "access": "UNKNOWN", "expires_at": null} ]
type내용
TEXT정화된 본문 text. 64KiB를 넘는 본문은 파일로 제공됩니다.
JSON발행 시 정한 schema로 검증된 data. 크면 data 대신 artifact_id로 파일 제공
FILEartifact_id, 파일 이름, MIME, 크기, sha256. Workflow와 Run의 다운로드 참고
URL외부 HTTPS 링크 url과 접근 방식(access). UpServe가 보관하거나 가용성을 보장하지 않습니다.
  • visibility는 INTERMEDIATE, PARTIAL, FINAL이며 최종 결과는 FINAL입니다.
  • availability가 FAILED나 EXPIRED인 항목은 error가 함께 옵니다.
  • 결과 목록은 한 번에 최대 100개, 응답 256KiB까지이며 after와 next_cursor로 이어 읽습니다.
  • 성공한 Turn은 발행 때 required로 정한 결과가 모두 있어야 합니다. 빠졌거나 형식이 틀리면 성공이 아니라 실패로 닫힙니다.

사용량

Turn과 Run 응답의 usage는 두 가지 상태입니다.

{"status": "PENDING", "total_su": null}
  • FINAL이면 total_su가 확정액입니다.
  • PENDING이면 비용이 아직 정해지지 않은 것이고 total_su는 null입니다. 0 SU가 아닙니다. 나중에 같은 조회를 다시 하면 확정됩니다.
  • GET /v1/usage는 key_id, deployment_id, session_id, turn_id, run_id 중 하나로 범위를 좁혀 확정액, 예약액, 항목별 내역을 보여 줍니다. (usage:read)
  • 같은 응답의 preparations는 조직 업무 만들기의 준비 비용을 따로 보여 줍니다. 모양은 위와 같은 상태·확정액·예약액·항목별 내역입니다. 준비가 진행 중이어도 실행 쪽 status와 total_su는 바뀌지 않습니다. 모든 Deployment를 허용받고 works:read를 가진 키에서는 Project 전체 비용이 실행 합계에 preparations 합계를 더한 값입니다.
    • 키에 works:read가 있으면 Project의 모든 준비가, 없으면 그 키로 접수한 준비만 들어갑니다. key_id를 주면 그 키로 접수한 준비로 좁혀집니다.
    • deployment_id, session_id, turn_id, run_id를 주면 preparations는 null입니다. 준비는 이들 어디에도 속하지 않기 때문입니다. 0 SU가 아닙니다.

질문 해소 (RequiredAction)

AI 직원이 실행 중 호출자에게 질문해야 할 때 Turn이 REQUIRES_ACTION으로 멈추는 기능입니다. 현재 Private Beta에서는 제공하지 않습니다. 서비스 전체 설정이며 Project별로 켤 수 없습니다. 지금은 발행된 Deployment에 질문 도구가 들어가지 않고, 사람의 답이나 승인이 필요해진 워크플로 실행은 ACTION_REQUIRED_UNSUPPORTED로 끝납니다. 아래는 이 기능이 제공될 때의 계약입니다.

  • 호출자가 답할 수 있는 질문(CALLER)은 POST /v1/sessions/{session_id}/actions/{action_id}/resolve로 답합니다. actions:resolve와 Idempotency-Key가 필요합니다.
  • 워크플로 승인에는 별도의 actions:approve 위임이 필요합니다. 고객 화면에서 사람이 결정하고 Run action API로 제출합니다. 워크플로 승인을 참고하세요.
  • 답변 기한이 지나면 409 ACTION_EXPIRED입니다.
curl -s -X POST "$BASE/v1/sessions/$SESSION_ID/actions/$ACTION_ID/resolve" \ -H "Authorization: Bearer $UPSERVE_API_KEY" \ -H "Idempotency-Key: answer-0001" \ -H "Content-Type: application/json" \ -d '{"answers":[{"question_id":"q1","text":"Use the Seoul office."}]}'