Skip to content

Add upstream Responses API service client #3

@HXYerror

Description

@HXYerror

Part of #1. Pairs with #2.

Goal

Add a new service module that POSTs to ${copilotBaseUrl(state)}/responses, parallel to the existing create-chat-completions.ts / create-embeddings.ts / get-models.ts clients.

Current state

src/services/copilot/ contains exactly three call sites, all hitting /chat/completions, /embeddings, /models. No code anywhere POSTs to a URL containing responses.

Tasks

  • Create src/services/copilot/create-responses.ts
    • Use undici's fetch (same as create-chat-completions.ts:31)
    • URL: \${copilotBaseUrl(state)}/responses``
    • Headers via the same helper that builds Copilot headers today (Authorization: Bearer ${state.copilotToken}, copilot-integration-id: vscode-chat, editor-version, editor-plugin-version, user-agent, x-github-api-version)
    • Add OpenAI-Beta: responses=experimental if/when upstream requires it (verify via VS Code Copilot Chat traffic; remove if not needed)
    • Honor state.showToken for debug logging
    • Support both streaming (SSE via fetch-event-stream) and non-streaming
  • Define response types in src/services/copilot/responses-types.ts:
    • ResponseObject with output: Array<ResponseOutputItem>
    • ResponseOutputItem discriminated union: reasoning | message | function_call | tool_call | image_generation_call | code_interpreter_call | local_shell_call | …
    • ResponseReasoningItem MUST include encrypted_content?: string (see Model-to-endpoint routing (chat vs responses) #5)
    • ResponseStreamEvent discriminated union covering response.created, response.in_progress, response.output_item.added, response.output_text.delta, response.output_text.done, response.reasoning.delta, response.reasoning_summary_text.delta, response.function_call_arguments.delta, response.completed, response.failed, etc.
  • Wire X-Initiator: agent | user header derived the same way create-chat-completions.ts:21–29 already does for chat (assistant/tool present in input → agent)
  • Wire Copilot-Vision-Request: true when input contains input_image (see Streaming reasoning events translation #10)

Acceptance criteria

  • await createResponses(payload, { stream: false }) returns a typed ResponseObject
  • await createResponses(payload, { stream: true }) returns an AsyncIterable<ResponseStreamEvent>
  • Errors from upstream surface as the existing HTTPError class (src/lib/error.ts)
  • Manual smoke test against gpt-5.3-codex returns at least one reasoning and one message output item

File pointers

  • src/services/copilot/create-chat-completions.ts — reference shape
  • src/lib/api-config.ts:16–19copilotBaseUrl
  • src/lib/error.ts
  • litellm reference: litellm/llms/github_copilot/responses/transformation.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    responses-apiOpenAI /v1/responses API support

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions