OpenResponses API (HTTP)

OpenClaw의 Gateway는 OpenResponses 호환 POST /v1/responses 엔드포인트를 제공할 수 있습니다.

이 엔드포인트는 기본적으로 비활성화되어 있습니다. 먼저 config에서 활성화해야 합니다.

  • POST /v1/responses
  • Gateway와 동일한 포트 (WS + HTTP 멀티플렉스): http://<gateway-host>:<port>/v1/responses

내부적으로 요청은 일반 Gateway agent 실행으로 처리되므로 (openclaw agent와 동일한 코드 경로), 라우팅/권한/설정이 Gateway 설정과 일치합니다.

인증

Gateway 인증 설정을 사용합니다. bearer token을 전송하세요:

  • Authorization: Bearer <token>

참고:

  • gateway.auth.mode="token"인 경우, gateway.auth.token (또는 OPENCLAW_GATEWAY_TOKEN)을 사용합니다.
  • gateway.auth.mode="password"인 경우, gateway.auth.password (또는 OPENCLAW_GATEWAY_PASSWORD)를 사용합니다.

Agent 선택

커스텀 헤더 불필요: OpenResponses model 필드에 agent id를 인코딩하세요:

  • model: "openclaw:<agentId>" (예: "openclaw:main", "openclaw:beta")
  • model: "agent:<agentId>" (별칭)

또는 헤더로 특정 OpenClaw agent를 지정:

  • x-openclaw-agent-id: <agentId> (기본값: main)

고급:

  • x-openclaw-session-key: <sessionKey>로 세션 라우팅을 완전히 제어할 수 있습니다.

엔드포인트 활성화

gateway.http.endpoints.responses.enabledtrue로 설정:

{
  gateway: {
    http: {
      endpoints: {
        responses: { enabled: true }
      }
    }
  }
}

엔드포인트 비활성화

gateway.http.endpoints.responses.enabledfalse로 설정:

{
  gateway: {
    http: {
      endpoints: {
        responses: { enabled: false }
      }
    }
  }
}

세션 동작

기본적으로 엔드포인트는 요청당 무상태(새로운 세션 키가 각 호출마다 생성됨)입니다.

요청에 OpenResponses user 문자열이 포함되어 있으면, Gateway는 이를 기반으로 안정적인 세션 키를 생성하여 반복 호출이 agent 세션을 공유할 수 있습니다.

요청 형식 (지원됨)

요청은 item 기반 입력을 갖춘 OpenResponses API를 따릅니다. 현재 지원:

  • input: 문자열 또는 item 객체 배열.
  • instructions: 시스템 프롬프트에 병합됨.
  • tools: 클라이언트 tool 정의 (function tools).
  • tool_choice: 클라이언트 tool 필터링 또는 요구.
  • stream: SSE 스트리밍 활성화.
  • max_output_tokens: 최선 노력 출력 제한 (제공자에 따라 다름).
  • user: 안정적인 세션 라우팅.

허용되지만 현재 무시됨:

  • max_tool_calls
  • reasoning
  • metadata
  • store
  • previous_response_id
  • truncation

Items (input)

message

역할: system, developer, user, assistant.

  • systemdeveloper는 시스템 프롬프트에 추가됩니다.
  • 가장 최근의 user 또는 function_call_output item이 "현재 메시지"가 됩니다.
  • 이전의 user/assistant 메시지들은 컨텍스트를 위한 히스토리로 포함됩니다.

function_call_output (turn 기반 tools)

tool 결과를 모델로 다시 전송:

{
  "type": "function_call_output",
  "call_id": "call_123",
  "output": "{\"temperature\": \"72F\"}"
}

reasoningitem_reference

스키마 호환성을 위해 허용되지만 프롬프트 생성 시 무시됩니다.

Tools (클라이언트 측 function tools)

tools: [{ type: "function", function: { name, description?, parameters? } }]로 tool을 제공합니다.

agent가 tool 호출을 결정하면, 응답은 function_call 출력 item을 반환합니다. 그런 다음 function_call_output이 포함된 후속 요청을 전송하여 turn을 계속합니다.

Images (input_image)

base64 또는 URL 소스 지원:

{
  "type": "input_image",
  "source": { "type": "url", "url": "https://example.com/image.png" }
}

허용되는 MIME 타입 (현재): image/jpeg, image/png, image/gif, image/webp. 최대 크기 (현재): 10MB.

Files (input_file)

base64 또는 URL 소스 지원:

{
  "type": "input_file",
  "source": {
    "type": "base64",
    "media_type": "text/plain",
    "data": "SGVsbG8gV29ybGQh",
    "filename": "hello.txt"
  }
}

허용되는 MIME 타입 (현재): text/plain, text/markdown, text/html, text/csv, application/json, application/pdf.

최대 크기 (현재): 5MB.

현재 동작:

  • 파일 콘텐츠는 디코딩되어 user 메시지가 아닌 시스템 프롬프트에 추가되므로 일시적으로 유지됩니다 (세션 히스토리에 저장되지 않음).
  • PDF는 텍스트 파싱됩니다. 텍스트가 거의 없으면, 첫 페이지들이 이미지로 래스터화되어 모델에 전달됩니다.

PDF 파싱은 Node 친화적인 pdfjs-dist 레거시 빌드를 사용합니다 (worker 없음). 최신 PDF.js 빌드는 브라우저 workers/DOM 전역 변수를 기대하므로 Gateway에서 사용되지 않습니다.

URL 가져오기 기본값:

  • files.allowUrl: true
  • images.allowUrl: true
  • 요청은 보호됩니다 (DNS 확인, 사설 IP 차단, 리다이렉트 제한, 타임아웃).

File + image 제한 (config)

기본값은 gateway.http.endpoints.responses 아래에서 조정할 수 있습니다:

{
  gateway: {
    http: {
      endpoints: {
        responses: {
          enabled: true,
          maxBodyBytes: 20000000,
          files: {
            allowUrl: true,
            allowedMimes: ["text/plain", "text/markdown", "text/html", "text/csv", "application/json", "application/pdf"],
            maxBytes: 5242880,
            maxChars: 200000,
            maxRedirects: 3,
            timeoutMs: 10000,
            pdf: {
              maxPages: 4,
              maxPixels: 4000000,
              minTextChars: 200
            }
          },
          images: {
            allowUrl: true,
            allowedMimes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
            maxBytes: 10485760,
            maxRedirects: 3,
            timeoutMs: 10000
          }
        }
      }
    }
  }
}

생략 시 기본값:

  • maxBodyBytes: 20MB
  • files.maxBytes: 5MB
  • files.maxChars: 200k
  • files.maxRedirects: 3
  • files.timeoutMs: 10s
  • files.pdf.maxPages: 4
  • files.pdf.maxPixels: 4,000,000
  • files.pdf.minTextChars: 200
  • images.maxBytes: 10MB
  • images.maxRedirects: 3
  • images.timeoutMs: 10s

스트리밍 (SSE)

stream: true로 설정하여 Server-Sent Events (SSE)를 수신:

  • Content-Type: text/event-stream
  • 각 이벤트 라인은 event: <type>data: <json>
  • 스트림은 data: [DONE]으로 종료

현재 발생하는 이벤트 타입:

  • response.created
  • response.in_progress
  • response.output_item.added
  • response.content_part.added
  • response.output_text.delta
  • response.output_text.done
  • response.content_part.done
  • response.output_item.done
  • response.completed
  • response.failed (오류 시)

Usage

usage는 기본 제공자가 token 수를 보고할 때 채워집니다.

오류

오류는 다음과 같은 JSON 객체를 사용합니다:

{ "error": { "message": "...", "type": "invalid_request_error" } }

일반적인 경우:

  • 401 인증 누락/유효하지 않음
  • 400 유효하지 않은 요청 본문
  • 405 잘못된 메서드

예제

비스트리밍:

curl -sS http://127.0.0.1:18789/v1/responses \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'x-openclaw-agent-id: main' \
  -d '{
    "model": "openclaw",
    "input": "hi"
  }'

스트리밍:

curl -N http://127.0.0.1:18789/v1/responses \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'x-openclaw-agent-id: main' \
  -d '{
    "model": "openclaw",
    "stream": true,
    "input": "hi"
  }'